From cb870c28c712244c43506f95caa244e05ac8547c Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Tue, 3 Dec 2013 23:49:21 +0100
Subject: [PATCH 001/147] Began testing of the
 MarkovAutomatonSparseTransitionParser to identify inflexibilities or bugs. -
 Noticed to my astonishment that seemingly arbitrary use of whitespaces (as
 long as each transition is in its own line) is no problem for the parser. -
 As predicted, handling of action labels of arbitrary length especially such
 starting with an '!' is not supported.

Next up: Handle arbitrary labels.


Former-commit-id: 339578e72a291ec6a143f6ed1f7d5fcee8642e6d
---
 .../MarkovAutomatonSparseTransitionParser.h   |   2 +-
 .../parser/MarkovAutomatonParserTest.cpp      | 178 ++++++++++++++++++
 2 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 test/functional/parser/MarkovAutomatonParserTest.cpp

diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index 0792b9c97..e84b80214 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -56,7 +56,7 @@ namespace storm {
                 // A bit vector indicating which states possess a Markovian choice.
                 storm::storage::BitVector markovianStates;
                 
-                // A vector that stores the exit rates for each
+                // A vector that stores the exit rates for each state. For all states that do not possess Markovian choices this is equal to 0.
                 std::vector<double> exitRates;
             };
             
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
new file mode 100644
index 000000000..93b02b3d2
--- /dev/null
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -0,0 +1,178 @@
+/*
+ * MarkovAutomatonParserTest.cpp
+ *
+ *  Created on: 03.12.2013
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+#include "src/settings/Settings.h"
+
+#include "src/parser/MarkovAutomatonSparseTransitionParser.h"
+#include "src/parser/Parser.h"
+
+#define STATE_COUNT 6
+#define CHOICE_COUNT 7
+
+TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
+
+	// The file that will be used for the test.
+	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra";
+
+	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
+
+	// Test all sizes and counts.
+	ASSERT_EQ(result.transitionMatrix.getColumnCount(), STATE_COUNT);
+	ASSERT_EQ(result.transitionMatrix.getRowCount(), CHOICE_COUNT);
+	ASSERT_EQ(result.transitionMatrix.getNonZeroEntryCount(), 12);
+	ASSERT_EQ(result.markovianChoices.getSize(), CHOICE_COUNT);
+	ASSERT_EQ(result.markovianStates.getSize(), STATE_COUNT);
+	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
+	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
+	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
+
+	// Test the general structure of the transition system (that will be an Markov automaton).
+
+	// Test the mapping between states and transition matrix rows.
+	ASSERT_EQ(result.nondeterministicChoiceIndices[0], 0);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[1], 1);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[2], 2);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[3], 3);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[4], 4);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[5], 6);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[6], 7);
+
+	// Test the Markovian states.
+	ASSERT_TRUE(result.markovianStates.get(0));
+	ASSERT_FALSE(result.markovianStates.get(1));
+	ASSERT_TRUE(result.markovianStates.get(2));
+	ASSERT_FALSE(result.markovianStates.get(3));
+	ASSERT_FALSE(result.markovianStates.get(4));
+	ASSERT_FALSE(result.markovianStates.get(5));
+
+	// Test the exit rates. These have to be 0 for all non-Markovian states.
+	ASSERT_EQ(result.exitRates[0], 2);
+	ASSERT_EQ(result.exitRates[1], 0);
+	ASSERT_EQ(result.exitRates[2], 15);
+	ASSERT_EQ(result.exitRates[3], 0);
+	ASSERT_EQ(result.exitRates[4], 0);
+	ASSERT_EQ(result.exitRates[5], 0);
+
+	// Finally, test the transition matrix itself.
+	ASSERT_EQ(result.transitionMatrix.getValue(0,1), 2);
+	ASSERT_EQ(result.transitionMatrix.getValue(1,2), 1);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,0), 1);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,1), 2);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,3), 4);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,4), 8);
+	ASSERT_EQ(result.transitionMatrix.getValue(3,2), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(3,3), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(4,3), 1);
+	ASSERT_EQ(result.transitionMatrix.getValue(5,1), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(5,5), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(6,5), 1);
+}
+
+TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
+	// The file that will be used for the test.
+	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespace_input_01.tra";
+
+	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
+
+	// Test all sizes and counts.
+	ASSERT_EQ(result.transitionMatrix.getColumnCount(), STATE_COUNT);
+	ASSERT_EQ(result.transitionMatrix.getRowCount(), CHOICE_COUNT);
+	ASSERT_EQ(result.transitionMatrix.getNonZeroEntryCount(), 12);
+	ASSERT_EQ(result.markovianChoices.getSize(), CHOICE_COUNT);
+	ASSERT_EQ(result.markovianStates.getSize(), STATE_COUNT);
+	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
+	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
+	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
+
+	// Test the general structure of the transition system (that will be an Markov automaton).
+
+	// Test the mapping between states and transition matrix rows.
+	ASSERT_EQ(result.nondeterministicChoiceIndices[0], 0);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[1], 1);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[2], 2);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[3], 3);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[4], 4);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[5], 6);
+	ASSERT_EQ(result.nondeterministicChoiceIndices[6], 7);
+
+	// Test the Markovian states.
+	ASSERT_TRUE(result.markovianStates.get(0));
+	ASSERT_FALSE(result.markovianStates.get(1));
+	ASSERT_TRUE(result.markovianStates.get(2));
+	ASSERT_FALSE(result.markovianStates.get(3));
+	ASSERT_FALSE(result.markovianStates.get(4));
+	ASSERT_FALSE(result.markovianStates.get(5));
+
+	// Test the exit rates. These have to be 0 for all non-Markovian states.
+	ASSERT_EQ(result.exitRates[0], 2);
+	ASSERT_EQ(result.exitRates[1], 0);
+	ASSERT_EQ(result.exitRates[2], 15);
+	ASSERT_EQ(result.exitRates[3], 0);
+	ASSERT_EQ(result.exitRates[4], 0);
+	ASSERT_EQ(result.exitRates[5], 0);
+
+	// Finally, test the transition matrix itself.
+	ASSERT_EQ(result.transitionMatrix.getValue(0,1), 2);
+	ASSERT_EQ(result.transitionMatrix.getValue(1,2), 1);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,0), 1);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,1), 2);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,3), 4);
+	ASSERT_EQ(result.transitionMatrix.getValue(2,4), 8);
+	ASSERT_EQ(result.transitionMatrix.getValue(3,2), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(3,3), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(4,3), 1);
+	ASSERT_EQ(result.transitionMatrix.getValue(5,1), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(5,5), 0.5);
+	ASSERT_EQ(result.transitionMatrix.getValue(6,5), 1);
+}
+
+//TODO: Deadlock Test. I am quite sure that the deadlock state handling does not behave quite right.
+//                     Find a way to test this by manipulating the fixDeadlocks flag of the settings.
+
+/*
+TEST(MarkovAutomatonSparseTransitionParserTest, DeadlockTest) {
+	// Save the fixDeadlocks flag, since it will be manipulated during the test.
+	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+	storm::settings::Settings::getInstance()->set("fixDeadlocks");
+
+
+	// The file that will be used for the test.
+	std::string filename = "/functional/parser/tra_files/ma_general_input_01.tra";
+
+	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
+
+	// Test if the result of the first pass has been transfered correctly
+	ASSERT_EQ(result.transitionMatrix.colCount, 7);
+	ASSERT_EQ(result.transitionMatrix.nonZeroEntryCount, 8);
+	ASSERT_EQ(result.markovianChoices.getNumberOfSetBits(), 2);
+
+	// Test the general structure of the transition system (that will be an Markov automaton).
+	//TODO
+
+	//Do the test again but this time without the fixDeadlock flag. This should throw an exception.
+	storm::settings::Settings::getInstance()->unset("fixDeadlocks");
+
+	bool thrown = false;
+
+	try {
+		// Parse the file, again.
+		result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
+	} catch(Exception &exception) {
+		// Print the exception and remember that it was thrown.
+		exception.print(std::cout);
+		thrown = true;
+	}
+
+	ASSERT_TRUE(thrown);
+
+	// Reset the fixDeadlocks flag to its original value.
+	if(fixDeadlocks) {
+		storm::settings::Settings::getInstance()->set("fixDeadlocks");
+	}
+}*/

From 9ce47989ed2ec665bd5fcffd226dbdc096d97de2 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Sat, 7 Dec 2013 15:45:33 +0100
Subject: [PATCH 002/147] The MA transition parser is now able to handle
 arbitrary labels.

Former-commit-id: 9643f41141530c4797c7bf80ed021540c1a7e463
---
 src/parser/MarkovAutomatonSparseTransitionParser.cpp | 12 ++++++------
 src/parser/Parser.cpp                                | 12 ++++++++++--
 src/parser/Parser.h                                  |  5 +++++
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 46bc05d2f..dc4d37888 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -57,12 +57,12 @@ namespace storm {
                 
                 // Depending on the action name, the choice is either a probabilitic one or a markovian one.
                 bool isMarkovianChoice = false;
-                if (buf[0] == '!') {
+                if (buf[0] == '!' &&  skipWord(buf) - buf == 1) {
                     isMarkovianChoice = true;
-                } else {
+                }else {
                     isMarkovianChoice = false;
                 }
-                ++buf;
+                buf = skipWord(buf);
                 
                 if (isMarkovianChoice) {
                     if (stateHasMarkovianChoice) {
@@ -99,7 +99,7 @@ namespace storm {
                         }
                     } else if (buf[0] == '*') {
                         // As we have encountered a "*", we know that there is an additional successor state for the current choice.
-                        ++buf;
+                        buf= skipWord(buf);
                         
                         // Now we need to read the successor state and check if we already saw a higher state index.
                         target = checked_strtol(buf, &buf);
@@ -180,7 +180,7 @@ namespace storm {
                 
                 // Depending on the action name, the choice is either a probabilitic one or a markovian one.
                 bool isMarkovianChoice = false;
-                if (buf[0] == '!') {
+                if (buf[0] == '!' && skipWord(buf) - buf == 1) {
                     isMarkovianChoice = true;
                     
                     // Mark the current state as a Markovian one.
@@ -209,7 +209,7 @@ namespace storm {
                         hasSuccessorState = true;
                         
                         // As we have encountered a "*", we know that there is an additional successor state for the current choice.
-                        ++buf;
+                        buf = skipWord(buf);
                         
                         // Now we need to read the successor state and check if we already saw a higher state index.
                         target = checked_strtol(buf, &buf);
diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp
index 5ed957c17..611afc9c6 100644
--- a/src/parser/Parser.cpp
+++ b/src/parser/Parser.cpp
@@ -60,7 +60,16 @@ bool storm::parser::fileExistsAndIsReadable(const char* fileName) {
 }
 
 /*!
- *	Skips spaces, tabs, newlines and carriage returns. Returns pointer
+ * Skips all numbers, letters and special characters.
+ * Returns a pointer to the first char that is a whitespace.
+ */
+char* storm::parser::skipWord(char* buf){
+	while((*buf != ' ') && (*buf != '\t') && (*buf != '\n') && (*buf != '\r')) buf++;
+	return buf;
+}
+
+/*!
+ *	Skips spaces, tabs, newlines and carriage returns. Returns a pointer
  *	to first char that is not a whitespace.
  *	@param buf String buffer
  *	@return	pointer to first non-whitespace character
@@ -78,7 +87,6 @@ storm::parser::SupportedLineEndingsEnum storm::parser::findUsedLineEndings(std::
 	char* buf = nullptr;
 	char* const bufferEnd = fileMap.dataend;
 
-	bool sawR = false;
 	for (buf = fileMap.data; buf != bufferEnd; ++buf) {
 		if (*buf == '\r') {
 			// check for following \n
diff --git a/src/parser/Parser.h b/src/parser/Parser.h
index f934ec50a..94e0cbb58 100644
--- a/src/parser/Parser.h
+++ b/src/parser/Parser.h
@@ -125,6 +125,11 @@ namespace parser {
 	 */
 	double checked_strtod(const char* str, char** end);
 	
+	/*!
+	 * @brief Skips all non whitespace characters until the next whitespace.
+	 */
+	char* skipWord(char* buf);
+
 	/*!
 	 *	@brief Skips common whitespaces in a string.
 	 */

From f8566e9dc26c8a927672a4b1ada0cffd0d605343 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Sun, 8 Dec 2013 00:49:56 +0100
Subject: [PATCH 003/147] A thousand things. - More tests. - Changed
 SparseStateRewardParser to a static class - Added comments here and there -
 Some reformatting. - Fixed some warnings. - Eliminated some unnecessary
 includes. - ...

Former-commit-id: efe1c96fee1cb8d89c0de2c0ffd2f8dfe4778ff7
---
 src/models/MarkovAutomaton.h                  | 156 +++---
 src/parser/DeterministicModelParser.cpp       |   2 +-
 src/parser/MarkovAutomatonParser.cpp          |  48 +-
 src/parser/MarkovAutomatonParser.h            |  41 +-
 .../MarkovAutomatonSparseTransitionParser.cpp | 518 +++++++++---------
 .../MarkovAutomatonSparseTransitionParser.h   | 174 +++---
 src/parser/NondeterministicModelParser.cpp    |   2 +-
 src/parser/Parser.cpp                         |  78 +--
 src/parser/Parser.h                           | 207 +++----
 src/parser/SparseStateRewardParser.cpp        |  48 +-
 src/parser/SparseStateRewardParser.h          |  15 +-
 .../parser/MarkovAutomatonParserTest.cpp      |  39 ++
 12 files changed, 691 insertions(+), 637 deletions(-)

diff --git a/src/models/MarkovAutomaton.h b/src/models/MarkovAutomaton.h
index 67e2a8acf..e08d16047 100644
--- a/src/models/MarkovAutomaton.h
+++ b/src/models/MarkovAutomaton.h
@@ -182,84 +182,84 @@ namespace storm {
                 return std::shared_ptr<AbstractModel<T>>(new MarkovAutomaton(newTransitionMatrix, this->getStateLabeling(), nondeterministicChoiceIndices, markovianStates, exitRates, this->hasStateRewards() ? this->getStateRewardVector() : boost::optional<std::vector<T>>(), this->hasTransitionRewards() ? this->getTransitionRewardMatrix() :  boost::optional<storm::storage::SparseMatrix<T>>(), this->hasChoiceLabeling() ? this->getChoiceLabeling() : boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>()));
             }
         
-        virtual void writeDotToStream(std::ostream& outStream, bool includeLabeling = true, storm::storage::BitVector const* subsystem = nullptr, std::vector<T> const* firstValue = nullptr, std::vector<T> const* secondValue = nullptr, std::vector<uint_fast64_t> const* stateColoring = nullptr, std::vector<std::string> const* colors = nullptr, std::vector<uint_fast64_t>* scheduler = nullptr, bool finalizeOutput = true) const override {
-        AbstractModel<T>::writeDotToStream(outStream, includeLabeling, subsystem, firstValue, secondValue, stateColoring, colors, scheduler, false);
-        
-        // Write the probability distributions for all the states.
-        auto rowIt = this->transitionMatrix.begin();
-        for (uint_fast64_t state = 0, highestStateIndex = this->getNumberOfStates() - 1; state <= highestStateIndex; ++state) {
-            uint_fast64_t rowCount = this->getNondeterministicChoiceIndices()[state + 1] - this->getNondeterministicChoiceIndices()[state];
-            bool highlightChoice = true;
-            
-            // For this, we need to iterate over all available nondeterministic choices in the current state.
-            for (uint_fast64_t row = 0; row < rowCount; ++row, ++rowIt) {
-                if (scheduler != nullptr) {
-                    // If the scheduler picked the current choice, we will not make it dotted, but highlight it.
-                    if ((*scheduler)[state] == row) {
-                        highlightChoice = true;
-                    } else {
-                        highlightChoice = false;
-                    }
-                }
-                
-                // If it's not a Markovian state or the current row is the first choice for this state, then we
-                // are dealing with a probabilitic choice.
-                if (!markovianStates.get(state) || row != 0) {
-                    // For each nondeterministic choice, we draw an arrow to an intermediate node to better display
-                    // the grouping of transitions.
-                    outStream << "\t\"" << state << "c" << row << "\" [shape = \"point\"";
-                    
-                    // If we were given a scheduler to highlight, we do so now.
-                    if (scheduler != nullptr) {
-                        if (highlightChoice) {
-                            outStream << ", fillcolor=\"red\"";
-                        }
-                    }
-                    outStream << "];" << std::endl;
-                    
-                    outStream << "\t" << state << " -> \"" << state << "c" << row << "\"";
-                    
-                    // If we were given a scheduler to highlight, we do so now.
-                    if (scheduler != nullptr) {
-                        if (highlightChoice) {
-                            outStream << " [color=\"red\", penwidth = 2]";
-                        } else {
-                            outStream << " [style = \"dotted\"]";
-                        }
-                    }
-                    outStream << ";" << std::endl;
-                    
-                    // Now draw all probabilitic arcs that belong to this nondeterminstic choice.
-                    for (auto transitionIt = rowIt.begin(), transitionIte = rowIt.end(); transitionIt != transitionIte; ++transitionIt) {
-                        if (subsystem == nullptr || subsystem->get(transitionIt.column())) {
-                            outStream << "\t\"" << state << "c" << row << "\" -> " << transitionIt.column() << " [ label= \"" << transitionIt.value() << "\" ]";
-                            
-                            // If we were given a scheduler to highlight, we do so now.
-                            if (scheduler != nullptr) {
-                                if (highlightChoice) {
-                                    outStream << " [color=\"red\", penwidth = 2]";
-                                } else {
-                                    outStream << " [style = \"dotted\"]";
-                                }
-                            }
-                            outStream << ";" << std::endl;
-                        }
-                    }
-                    } else {
-                        // In this case we are emitting a Markovian choice, so draw the arrows directly to the target states.
-                        for (auto transitionIt = rowIt.begin(), transitionIte = rowIt.end(); transitionIt != transitionIte; ++transitionIt) {
-                            if (subsystem == nullptr || subsystem->get(transitionIt.column())) {
-                                outStream << "\t\"" << state << "\" -> " << transitionIt.column() << " [ label= \"" << transitionIt.value() << " (" << this->exitRates[state] << ")\" ]";
-                            }
-                        }
-                    }
-                    }
-                    }
-                    
-                    if (finalizeOutput) {
-                        outStream << "}" << std::endl;
-                    }
-                    }
+			virtual void writeDotToStream(std::ostream& outStream, bool includeLabeling = true, storm::storage::BitVector const* subsystem = nullptr, std::vector<T> const* firstValue = nullptr, std::vector<T> const* secondValue = nullptr, std::vector<uint_fast64_t> const* stateColoring = nullptr, std::vector<std::string> const* colors = nullptr, std::vector<uint_fast64_t>* scheduler = nullptr, bool finalizeOutput = true) const override {
+			AbstractModel<T>::writeDotToStream(outStream, includeLabeling, subsystem, firstValue, secondValue, stateColoring, colors, scheduler, false);
+
+			// Write the probability distributions for all the states.
+			auto rowIt = this->transitionMatrix.begin();
+			for (uint_fast64_t state = 0, highestStateIndex = this->getNumberOfStates() - 1; state <= highestStateIndex; ++state) {
+				uint_fast64_t rowCount = this->getNondeterministicChoiceIndices()[state + 1] - this->getNondeterministicChoiceIndices()[state];
+				bool highlightChoice = true;
+
+				// For this, we need to iterate over all available nondeterministic choices in the current state.
+				for (uint_fast64_t row = 0; row < rowCount; ++row, ++rowIt) {
+					if (scheduler != nullptr) {
+						// If the scheduler picked the current choice, we will not make it dotted, but highlight it.
+						if ((*scheduler)[state] == row) {
+							highlightChoice = true;
+						} else {
+							highlightChoice = false;
+						}
+					}
+
+					// If it's not a Markovian state or the current row is the first choice for this state, then we
+					// are dealing with a probabilitic choice.
+					if (!markovianStates.get(state) || row != 0) {
+						// For each nondeterministic choice, we draw an arrow to an intermediate node to better display
+						// the grouping of transitions.
+						outStream << "\t\"" << state << "c" << row << "\" [shape = \"point\"";
+
+						// If we were given a scheduler to highlight, we do so now.
+						if (scheduler != nullptr) {
+							if (highlightChoice) {
+								outStream << ", fillcolor=\"red\"";
+							}
+						}
+						outStream << "];" << std::endl;
+
+						outStream << "\t" << state << " -> \"" << state << "c" << row << "\"";
+
+						// If we were given a scheduler to highlight, we do so now.
+						if (scheduler != nullptr) {
+							if (highlightChoice) {
+								outStream << " [color=\"red\", penwidth = 2]";
+							} else {
+								outStream << " [style = \"dotted\"]";
+							}
+						}
+						outStream << ";" << std::endl;
+
+						// Now draw all probabilitic arcs that belong to this nondeterminstic choice.
+						for (auto transitionIt = rowIt.begin(), transitionIte = rowIt.end(); transitionIt != transitionIte; ++transitionIt) {
+							if (subsystem == nullptr || subsystem->get(transitionIt.column())) {
+								outStream << "\t\"" << state << "c" << row << "\" -> " << transitionIt.column() << " [ label= \"" << transitionIt.value() << "\" ]";
+
+								// If we were given a scheduler to highlight, we do so now.
+								if (scheduler != nullptr) {
+									if (highlightChoice) {
+										outStream << " [color=\"red\", penwidth = 2]";
+									} else {
+										outStream << " [style = \"dotted\"]";
+									}
+								}
+								outStream << ";" << std::endl;
+							}
+						}
+						} else {
+							// In this case we are emitting a Markovian choice, so draw the arrows directly to the target states.
+							for (auto transitionIt = rowIt.begin(), transitionIte = rowIt.end(); transitionIt != transitionIte; ++transitionIt) {
+								if (subsystem == nullptr || subsystem->get(transitionIt.column())) {
+									outStream << "\t\"" << state << "\" -> " << transitionIt.column() << " [ label= \"" << transitionIt.value() << " (" << this->exitRates[state] << ")\" ]";
+								}
+							}
+						}
+					}
+				}
+
+				if (finalizeOutput) {
+					outStream << "}" << std::endl;
+				}
+			}
 		private:
 
             /*!
diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index 2637f1be0..1b5ec197c 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -39,7 +39,7 @@ DeterministicModelParserResultContainer<double> parseDeterministicModel(std::str
 	DeterministicModelParserResultContainer<double> result(std::move(resultTransitionSystem), std::move(resultLabeling));
 
 	if (stateRewardFile != "") {
-		result.stateRewards.reset(storm::parser::SparseStateRewardParser(stateCount, stateRewardFile));
+		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
 	}
 	if (transitionRewardFile != "") {
 		RewardMatrixInformationStruct* rewardMatrixInfo = new RewardMatrixInformationStruct(rowCount, stateCount, nullptr);
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index 28b91b6d9..8b74a896b 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -3,26 +3,28 @@
 #include "SparseStateRewardParser.h"
 
 namespace storm {
-    namespace parser {
-        
-        storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename) {
-            storm::parser::MarkovAutomatonSparseTransitionParser::ResultType transitionResult(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(transitionsFilename));
-            storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionResult.transitionMatrix.getColumnCount(), labelingFilename));
-
-            boost::optional<std::vector<double>> stateRewards;
-            if (stateRewardFilename != "") {
-                stateRewards.reset(storm::parser::SparseStateRewardParser(transitionResult.transitionMatrix.getColumnCount(), stateRewardFilename));
-            }
-            
-            if (transitionRewardFilename != "") {
-                LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata.");
-                throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
-            }
-            
-            storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionResult.transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
-            
-            return resultingAutomaton;
-        }
-        
-    } // namespace parser
-} // namespace storm
\ No newline at end of file
+
+namespace parser {
+
+storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename) {
+	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType transitionResult(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(transitionsFilename));
+	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionResult.transitionMatrix.getColumnCount(), labelingFilename));
+
+	boost::optional<std::vector<double>> stateRewards;
+	if (stateRewardFilename != "") {
+		stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(transitionResult.transitionMatrix.getColumnCount(), stateRewardFilename));
+	}
+
+	if (transitionRewardFilename != "") {
+		LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata.");
+		throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
+	}
+
+	storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionResult.transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
+
+	return resultingAutomaton;
+}
+
+} // namespace parser
+
+} // namespace storm
diff --git a/src/parser/MarkovAutomatonParser.h b/src/parser/MarkovAutomatonParser.h
index c63274630..53354ba55 100644
--- a/src/parser/MarkovAutomatonParser.h
+++ b/src/parser/MarkovAutomatonParser.h
@@ -5,25 +5,28 @@
 #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
 
 namespace storm {
-    namespace parser {
-        
-        /*!
-         * A class providing the functionality to parse a labeled Markov automaton.
-         */
-        class MarkovAutomatonParser {
-        public:
-            
-            /*!
-             * Parses the given Markov automaton and returns an object representing the automaton.
-             *
-             * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
-             * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
-             * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
-             * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
-             */
-            static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename);
-        };
-    } // namespace parser
+
+namespace parser {
+
+/*!
+ * A class providing the functionality to parse a labeled Markov automaton.
+ */
+class MarkovAutomatonParser {
+public:
+
+	/*!
+	 * Parses the given Markov automaton and returns an object representing the automaton.
+	 *
+	 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
+	 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
+	 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
+	 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
+	 */
+	static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename);
+};
+
+} // namespace parser
+
 } // namespace storm
 
 #endif /* STORM_PARSER_MARKOVAUTOMATONPARSER_H_ */
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index dc4d37888..94145fb66 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -3,264 +3,262 @@
 #include "src/settings/Settings.h"
 
 namespace storm {
-    namespace parser {
- 
-        MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings) {
-            MarkovAutomatonSparseTransitionParser::FirstPassResult result;
-
-            bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-            
-            // Skip the format hint.
-            buf = storm::parser::forwardToNextLine(buf, lineEndings);
-            
-            // Now read the transitions.
-            int_fast64_t source, target = -1;
-            int_fast64_t lastsource = -1;
-            bool encounteredEOF = false;
-            bool stateHasMarkovianChoice = false;
-            bool stateHasProbabilisticChoice = false;
-            while (buf[0] != '\0' && !encounteredEOF) {
-                // At the current point, the next thing to read is the source state of the next choice to come.
-                source = checked_strtol(buf, &buf);
-                
-                // Check if we encountered a state index that is bigger than all previously seen ones and record it if necessary.
-                if (source > result.highestStateIndex) {
-                    result.highestStateIndex = source;
-                }
-                
-                // If we have skipped some states, we need to reserve the space for the self-loop insertion in the second pass.
-                if (source > lastsource + 1) {
-                    if (fixDeadlocks) {
-                        result.numberOfNonzeroEntries += source - lastsource - 1;
-                        result.numberOfChoices += source - lastsource - 1;
-                    } else {
-                        LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
-                        throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
-                    }
-                } else if (source < lastsource) {
-                    LOG4CPLUS_ERROR(logger, "Illegal state choice order. A choice of state " << source << " appears at an illegal position.");
-                    throw storm::exceptions::WrongFormatException() << "Illegal state choice order. A choice of state " << source << " appears at an illegal position.";
-                }
-                
-                ++result.numberOfChoices;
-                
-                // If we have moved to the next state, we need to clear the flag that stores whether or not the source has a Markovian or probabilistic choice.
-                if (source != lastsource) {
-                    stateHasMarkovianChoice = false;
-                    stateHasProbabilisticChoice = false;
-                }
-                
-                // Record that the current source was the last source.
-                lastsource = source;
-                
-                buf = trimWhitespaces(buf);
-                
-                // Depending on the action name, the choice is either a probabilitic one or a markovian one.
-                bool isMarkovianChoice = false;
-                if (buf[0] == '!' &&  skipWord(buf) - buf == 1) {
-                    isMarkovianChoice = true;
-                }else {
-                    isMarkovianChoice = false;
-                }
-                buf = skipWord(buf);
-                
-                if (isMarkovianChoice) {
-                    if (stateHasMarkovianChoice) {
-                        LOG4CPLUS_ERROR(logger, "The state " << source << " has multiple Markovian choices.");
-                        throw storm::exceptions::WrongFormatException() << "The state " << source << " has multiple Markovian choices.";
-                    }
-                    if (stateHasProbabilisticChoice) {
-                        LOG4CPLUS_ERROR(logger, "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.");
-                        throw storm::exceptions::WrongFormatException() << "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.";
-                    }
-                    stateHasMarkovianChoice = true;
-                } else {
-                    stateHasProbabilisticChoice = true;
-                }
-                
-                buf = forwardToNextLine(buf, lineEndings);
-                
-                // Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
-                bool hasSuccessorState = false;
-                bool encounteredNewDistribution = false;
-                uint_fast64_t lastSuccessorState = 0;
-                
-                // At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
-                do {
-                    buf = trimWhitespaces(buf);
-                    // If the end of the file was reached, we need to abort and check whether we are in a legal state.
-                    if (buf[0] == '\0') {
-                        if (!hasSuccessorState) {
-                            LOG4CPLUS_ERROR(logger, "Premature end-of-file. Expected at least one successor state for state " << source << ".");
-                            throw storm::exceptions::WrongFormatException() << "Premature end-of-file. Expected at least one successor state for state " << source << ".";
-                        } else {
-                            // If there was at least one successor for the current choice, this is legal and we need to move on.
-                            encounteredEOF = true;
-                        }
-                    } else if (buf[0] == '*') {
-                        // As we have encountered a "*", we know that there is an additional successor state for the current choice.
-                        buf= skipWord(buf);
-                        
-                        // Now we need to read the successor state and check if we already saw a higher state index.
-                        target = checked_strtol(buf, &buf);
-                        if (target > result.highestStateIndex) {
-                            result.highestStateIndex = target;
-                        }
-                        if (hasSuccessorState && target <= lastSuccessorState) {
-                            LOG4CPLUS_ERROR(logger, "Illegal transition order for source state " << source << ".");
-                            throw storm::exceptions::WrongFormatException() << "Illegal transition order for source state " << source << ".";
-                        }
-                        
-                        // And the corresponding probability/rate.
-                        double val = checked_strtod(buf, &buf);
-                        if (val <= 0.0) {
-                            LOG4CPLUS_ERROR(logger, "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
-                            throw storm::exceptions::WrongFormatException() << "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
-                        }
-                        
-                        // We need to record that we found at least one successor state for the current choice.
-                        hasSuccessorState = true;
-                        lastSuccessorState = target;
-                        
-                        // As we found a new successor, we need to increase the number of nonzero entries.
-                        ++result.numberOfNonzeroEntries;
-                        
-                        buf = forwardToNextLine(buf, lineEndings);
-                    } else {
-                        // If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
-                        // to the buffer, because we still need to read the new source state.
-                        encounteredNewDistribution = true;
-                    }
-                } while (!encounteredEOF && !encounteredNewDistribution);
-            }
-            
-            return result;
-        }
-        
-        MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, SupportedLineEndingsEnum lineEndings, FirstPassResult const& firstPassResult) {
-            ResultType result(firstPassResult);
-            
-            bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-            
-            // Skip the format hint.
-            buf = storm::parser::forwardToNextLine(buf, lineEndings);
-            
-            // Now read the transitions.
-            int_fast64_t source, target = -1;
-            int_fast64_t lastsource = -1;
-            bool encounteredEOF = false;
-            uint_fast64_t currentChoice = 0;
-            while (buf[0] != '\0' && !encounteredEOF) {
-                // At the current point, the next thing to read is the source state of the next choice to come.
-                source = checked_strtol(buf, &buf);
-                                
-                // If we have skipped some states, we need to insert self-loops if requested.
-                if (source > lastsource + 1) {
-                    if (fixDeadlocks) {
-                        for (uint_fast64_t index = lastsource + 1; index < source; ++index) {
-                            result.nondeterministicChoiceIndices[index] = currentChoice;
-                            result.transitionMatrix.addNextValue(currentChoice, index, 1);
-                            ++currentChoice;
-                        }
-                    } else {
-                        LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
-                        throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
-                    }
-                }
-                
-                if (source != lastsource) {
-                    // If we skipped to a new state we need to record the beginning of the choices in the nondeterministic choice indices.
-                    result.nondeterministicChoiceIndices[source] = currentChoice;
-                }
-                
-                // Record that the current source was the last source.
-                lastsource = source;
-                
-                buf = trimWhitespaces(buf);
-                
-                // Depending on the action name, the choice is either a probabilitic one or a markovian one.
-                bool isMarkovianChoice = false;
-                if (buf[0] == '!' && skipWord(buf) - buf == 1) {
-                    isMarkovianChoice = true;
-                    
-                    // Mark the current state as a Markovian one.
-                    result.markovianStates.set(source, true);
-                } else {
-                    isMarkovianChoice = false;
-                }
-                
-                buf = forwardToNextLine(buf, lineEndings);
-                
-                // Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
-                bool hasSuccessorState = false;
-                bool encounteredNewDistribution = false;
-                
-                // At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
-                do {
-                    buf = trimWhitespaces(buf);
-                    
-                    // If the end of the file was reached, we need to abort and check whether we are in a legal state.
-                    if (buf[0] == '\0') {
-                        // Under the assumption that the currently open choice has at least one successor (which is given after the first run)
-                        // we may legally stop reading here.
-                        encounteredEOF = true;
-                    } else if (buf[0] == '*') {
-                        // We need to record that we found at least one successor state for the current choice.
-                        hasSuccessorState = true;
-                        
-                        // As we have encountered a "*", we know that there is an additional successor state for the current choice.
-                        buf = skipWord(buf);
-                        
-                        // Now we need to read the successor state and check if we already saw a higher state index.
-                        target = checked_strtol(buf, &buf);
-                        
-                        // And the corresponding probability/rate.
-                        double val = checked_strtod(buf, &buf);
-                        
-                        // Record the value as well as the exit rate in case of a Markovian choice.
-                        result.transitionMatrix.addNextValue(currentChoice, target, val);
-                        if (isMarkovianChoice) {
-                            result.exitRates[source] += val;
-                        }
-                        
-                        buf = forwardToNextLine(buf, lineEndings);
-                    } else {
-                        // If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
-                        // to the buffer, because we still need to read the new source state.
-                        encounteredNewDistribution = true;
-                    }
-                } while (!encounteredEOF && !encounteredNewDistribution);
-                
-                ++currentChoice;
-            }
-            
-            // As we have added all entries at this point, we need to finalize the matrix.
-            result.transitionMatrix.finalize();
-            
-            // Put a sentinel element at the end.
-            result.nondeterministicChoiceIndices[firstPassResult.highestStateIndex + 1] = currentChoice;
-            
-            return result;
-        }
-        
-        MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(std::string const& filename) {
-            // Set the locale to correctly recognize floating point numbers.
-            setlocale(LC_NUMERIC, "C");
-            
-            if (!fileExistsAndIsReadable(filename.c_str())) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-                throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
-            }
-            
-            // Determine used line endings.
-            SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
-            
-            // Open file and prepare pointer to buffer.
-            MappedFile file(filename.c_str());
-            char* buf = file.data;
-            
-            return secondPass(buf, lineEndings, firstPass(buf, lineEndings));
-        }
-        
-    } // namespace parser
+
+namespace parser {
+
+MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings) {
+	MarkovAutomatonSparseTransitionParser::FirstPassResult result;
+
+	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+
+	// Skip the format hint.
+	buf = storm::parser::forwardToNextLine(buf, lineEndings);
+
+	// Now read the transitions.
+	int_fast64_t source, target = -1;
+	int_fast64_t lastsource = -1;
+	bool encounteredEOF = false;
+	bool stateHasMarkovianChoice = false;
+	bool stateHasProbabilisticChoice = false;
+	while (buf[0] != '\0' && !encounteredEOF) {
+		// At the current point, the next thing to read is the source state of the next choice to come.
+		source = checked_strtol(buf, &buf);
+
+		// Check if we encountered a state index that is bigger than all previously seen ones and record it if necessary.
+		if (source > result.highestStateIndex) {
+			result.highestStateIndex = source;
+		}
+
+		// If we have skipped some states, we need to reserve the space for the self-loop insertion in the second pass.
+		if (source > lastsource + 1) {
+			if (fixDeadlocks) {
+				result.numberOfNonzeroEntries += source - lastsource - 1;
+				result.numberOfChoices += source - lastsource - 1;
+			} else {
+				LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
+				throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
+			}
+		} else if (source < lastsource) {
+			LOG4CPLUS_ERROR(logger, "Illegal state choice order. A choice of state " << source << " appears at an illegal position.");
+			throw storm::exceptions::WrongFormatException() << "Illegal state choice order. A choice of state " << source << " appears at an illegal position.";
+		}
+
+		++result.numberOfChoices;
+
+		// If we have moved to the next state, we need to clear the flag that stores whether or not the source has a Markovian or probabilistic choice.
+		if (source != lastsource) {
+			stateHasMarkovianChoice = false;
+			stateHasProbabilisticChoice = false;
+		}
+
+		// Record that the current source was the last source.
+		lastsource = source;
+
+		buf = trimWhitespaces(buf);
+
+		// Depending on the action name, the choice is either a probabilitic one or a markovian one.
+		bool isMarkovianChoice = false;
+		if (buf[0] == '!' &&  skipWord(buf) - buf == 1) {
+			isMarkovianChoice = true;
+		}else {
+			isMarkovianChoice = false;
+		}
+		buf = skipWord(buf);
+
+		if (isMarkovianChoice) {
+			if (stateHasMarkovianChoice) {
+				LOG4CPLUS_ERROR(logger, "The state " << source << " has multiple Markovian choices.");
+				throw storm::exceptions::WrongFormatException() << "The state " << source << " has multiple Markovian choices.";
+			}
+			if (stateHasProbabilisticChoice) {
+				LOG4CPLUS_ERROR(logger, "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.");
+				throw storm::exceptions::WrongFormatException() << "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.";
+			}
+			stateHasMarkovianChoice = true;
+		} else {
+			stateHasProbabilisticChoice = true;
+		}
+
+		buf = forwardToNextLine(buf, lineEndings);
+
+		// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
+		bool hasSuccessorState = false;
+		bool encounteredNewDistribution = false;
+		uint_fast64_t lastSuccessorState = 0;
+
+		// At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
+		do {
+			buf = trimWhitespaces(buf);
+			// If the end of the file was reached, we need to abort and check whether we are in a legal state.
+			if (buf[0] == '\0') {
+				if (!hasSuccessorState) {
+					LOG4CPLUS_ERROR(logger, "Premature end-of-file. Expected at least one successor state for state " << source << ".");
+					throw storm::exceptions::WrongFormatException() << "Premature end-of-file. Expected at least one successor state for state " << source << ".";
+				} else {
+					// If there was at least one successor for the current choice, this is legal and we need to move on.
+					encounteredEOF = true;
+				}
+			} else if (buf[0] == '*') {
+				// As we have encountered a "*", we know that there is an additional successor state for the current choice.
+				buf= skipWord(buf);
+
+				// Now we need to read the successor state and check if we already saw a higher state index.
+				target = checked_strtol(buf, &buf);
+				if (target > result.highestStateIndex) {
+					result.highestStateIndex = target;
+				}
+				if (hasSuccessorState && target <= lastSuccessorState) {
+					LOG4CPLUS_ERROR(logger, "Illegal transition order for source state " << source << ".");
+					throw storm::exceptions::WrongFormatException() << "Illegal transition order for source state " << source << ".";
+				}
+
+				// And the corresponding probability/rate.
+				double val = checked_strtod(buf, &buf);
+				if (val <= 0.0) {
+					LOG4CPLUS_ERROR(logger, "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
+					throw storm::exceptions::WrongFormatException() << "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
+				}
+
+				// We need to record that we found at least one successor state for the current choice.
+				hasSuccessorState = true;
+				lastSuccessorState = target;
+
+				// As we found a new successor, we need to increase the number of nonzero entries.
+				++result.numberOfNonzeroEntries;
+
+				buf = forwardToNextLine(buf, lineEndings);
+			} else {
+				// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
+				// to the buffer, because we still need to read the new source state.
+				encounteredNewDistribution = true;
+			}
+		} while (!encounteredEOF && !encounteredNewDistribution);
+	}
+
+	return result;
+}
+
+MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, SupportedLineEndingsEnum lineEndings, FirstPassResult const& firstPassResult) {
+	ResultType result(firstPassResult);
+
+	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+
+	// Skip the format hint.
+	buf = storm::parser::forwardToNextLine(buf, lineEndings);
+
+	// Now read the transitions.
+	int_fast64_t source, target = -1;
+	int_fast64_t lastsource = -1;
+	bool encounteredEOF = false;
+	uint_fast64_t currentChoice = 0;
+	while (buf[0] != '\0' && !encounteredEOF) {
+		// At the current point, the next thing to read is the source state of the next choice to come.
+		source = checked_strtol(buf, &buf);
+
+		// If we have skipped some states, we need to insert self-loops if requested.
+		if (source > lastsource + 1) {
+			if (fixDeadlocks) {
+				for (uint_fast64_t index = lastsource + 1; index < source; ++index) {
+					result.nondeterministicChoiceIndices[index] = currentChoice;
+					result.transitionMatrix.addNextValue(currentChoice, index, 1);
+					++currentChoice;
+				}
+			} else {
+				LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
+				throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
+			}
+		}
+
+		if (source != lastsource) {
+			// If we skipped to a new state we need to record the beginning of the choices in the nondeterministic choice indices.
+			result.nondeterministicChoiceIndices[source] = currentChoice;
+		}
+
+		// Record that the current source was the last source.
+		lastsource = source;
+
+		buf = trimWhitespaces(buf);
+
+		// Depending on the action name, the choice is either a probabilitic one or a markovian one.
+		bool isMarkovianChoice = false;
+		if (buf[0] == '!' && skipWord(buf) - buf == 1) {
+			isMarkovianChoice = true;
+
+			// Mark the current state as a Markovian one.
+			result.markovianStates.set(source, true);
+		} else {
+			isMarkovianChoice = false;
+		}
+
+		buf = forwardToNextLine(buf, lineEndings);
+
+		// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
+		bool encounteredNewDistribution = false;
+
+		// At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
+		do {
+			buf = trimWhitespaces(buf);
+
+			// If the end of the file was reached, we need to abort and check whether we are in a legal state.
+			if (buf[0] == '\0') {
+				// Under the assumption that the currently open choice has at least one successor (which is given after the first run)
+				// we may legally stop reading here.
+				encounteredEOF = true;
+			} else if (buf[0] == '*') {
+
+				// As we have encountered a "*", we know that there is an additional successor state for the current choice.
+				buf = skipWord(buf);
+
+				// Now we need to read the successor state and check if we already saw a higher state index.
+				target = checked_strtol(buf, &buf);
+
+				// And the corresponding probability/rate.
+				double val = checked_strtod(buf, &buf);
+
+				// Record the value as well as the exit rate in case of a Markovian choice.
+				result.transitionMatrix.addNextValue(currentChoice, target, val);
+				if (isMarkovianChoice) {
+					result.exitRates[source] += val;
+				}
+
+				buf = forwardToNextLine(buf, lineEndings);
+			} else {
+				// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
+				// to the buffer, because we still need to read the new source state.
+				encounteredNewDistribution = true;
+			}
+		} while (!encounteredEOF && !encounteredNewDistribution);
+
+		++currentChoice;
+	}
+
+	// As we have added all entries at this point, we need to finalize the matrix.
+	result.transitionMatrix.finalize();
+
+	// Put a sentinel element at the end.
+	result.nondeterministicChoiceIndices[firstPassResult.highestStateIndex + 1] = currentChoice;
+
+	return result;
+}
+
+MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(std::string const& filename) {
+	// Set the locale to correctly recognize floating point numbers.
+	setlocale(LC_NUMERIC, "C");
+
+	if (!fileExistsAndIsReadable(filename.c_str())) {
+		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+		throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
+	}
+
+	// Determine used line endings.
+	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+
+	// Open file and prepare pointer to buffer.
+	MappedFile file(filename.c_str());
+	char* buf = file.data;
+
+	return secondPass(buf, lineEndings, firstPass(buf, lineEndings));
+}
+
+} // namespace parser
 } // namespace storm
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index e84b80214..e576730d2 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -6,90 +6,96 @@
 #include "Parser.h"
 
 namespace storm {
-    namespace parser {
-        
-        /*
-         * A class providing the functionality to parse the transitions of a Markov automaton.
-         */
-        class MarkovAutomatonSparseTransitionParser {
-        public:
-            /*
-             * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model, the highest state index
-             * and the total number of choices.
-             */
-            struct FirstPassResult {
-                
-                FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0), numberOfChoices(0) {
-                    // Intentionally left empty.
-                }
-
-                // The total number of non-zero entries of the model.
-                uint_fast64_t numberOfNonzeroEntries;
-                
-                // The highest state index that appears in the model.
-                uint_fast64_t highestStateIndex;
-                
-                // The total number of choices in the model.
-                uint_fast64_t numberOfChoices;
-            };
-            
-            /*
-             * A structure representing the result of the parser. It contains the sparse matrix that represents the transitions (along with a vector indicating
-             * at which index the choices of a given state begin) as well as the exit rates for all Markovian choices.
-             */
-            struct ResultType {
-                
-                ResultType(FirstPassResult const& firstPassResult) : transitionMatrix(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
-                    transitionMatrix.initialize(firstPassResult.numberOfNonzeroEntries);
-                    // Intentionally left empty.
-                }
-                
-                // A matrix representing the transitions of the model.
-                storm::storage::SparseMatrix<double> transitionMatrix;
-                
-                // A vector indicating which rows of the matrix represent the choices of a given state.
-                std::vector<uint_fast64_t> nondeterministicChoiceIndices;
-                
-                // A bit vector indicating which choices are Markovian. By duality, all other choices are probabilitic.
-                storm::storage::BitVector markovianChoices;
-                
-                // A bit vector indicating which states possess a Markovian choice.
-                storm::storage::BitVector markovianStates;
-                
-                // A vector that stores the exit rates for each state. For all states that do not possess Markovian choices this is equal to 0.
-                std::vector<double> exitRates;
-            };
-            
-            /*!
-             * Parses the given file under the assumption that it contains a Markov automaton specified in the appropriate format.
-             *
-             * @param filename The name of the file to parse.
-             * @return A structure representing the result of the parser.
-             */
-            static ResultType parseMarkovAutomatonTransitions(std::string const& filename);
-            
-        private:
-            /*
-             * Performs the first pass on the input pointed to by the given buffer.
-             *
-             * @param buffer The buffer that cointains the input.
-             * @param lineEndings The line endings that are to be used while parsing.
-             * @return A structure representing the result of the first pass.
-             */
-            static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings);
-            
-            /*
-             * Performs the second pass on the input pointed to by the given buffer with the information of the first pass.
-             *
-             * @param buffer The buffer that cointains the input.
-             * @param lineEndings The line endings that are to be used while parsing.
-             * @param firstPassResult The result of the first pass performed on the same input.
-             * @return A structure representing the result of the second pass.
-             */
-            static ResultType secondPass(char* buffer, SupportedLineEndingsEnum lineEndings, FirstPassResult const& firstPassResult);
-        };
-        
-    } // namespace parser
+
+namespace parser {
+
+/*
+ * A class providing the functionality to parse the transitions of a Markov automaton.
+ */
+class MarkovAutomatonSparseTransitionParser {
+public:
+	/*
+	 * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model, the highest state index
+	 * and the total number of choices.
+	 */
+	struct FirstPassResult {
+
+		FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0), numberOfChoices(0) {
+			// Intentionally left empty.
+		}
+
+		// The total number of non-zero entries of the model.
+		uint_fast64_t numberOfNonzeroEntries;
+
+		// The highest state index that appears in the model.
+		uint_fast64_t highestStateIndex;
+
+		// The total number of choices in the model.
+		uint_fast64_t numberOfChoices;
+	};
+
+	/*
+	 * A structure representing the result of the parser. It contains the sparse matrix that represents the transitions (along with a vector indicating
+	 * at which index the choices of a given state begin) as well as the exit rates for all Markovian choices.
+	 */
+	struct ResultType {
+
+		/*
+		 * Creates a new instance of the struct using the result of the first pass to correctly initialize the container.
+		 * @param firstPassResult A reference to the result of the first pass.
+		 */
+		ResultType(FirstPassResult const& firstPassResult) : transitionMatrix(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
+			transitionMatrix.initialize(firstPassResult.numberOfNonzeroEntries);
+			// Intentionally left empty.
+		}
+
+		// A matrix representing the transitions of the model.
+		storm::storage::SparseMatrix<double> transitionMatrix;
+
+		// A vector indicating which rows of the matrix represent the choices of a given state.
+		std::vector<uint_fast64_t> nondeterministicChoiceIndices;
+
+		// A bit vector indicating which choices are Markovian. By duality, all other choices are probabilitic.
+		storm::storage::BitVector markovianChoices;
+
+		// A bit vector indicating which states possess a Markovian choice.
+		storm::storage::BitVector markovianStates;
+
+		// A vector that stores the exit rates for each state. For all states that do not possess Markovian choices this is equal to 0.
+		std::vector<double> exitRates;
+	};
+
+	/*!
+	 * Parses the given file under the assumption that it contains a Markov automaton specified in the appropriate format.
+	 *
+	 * @param filename The name of the file to parse.
+	 * @return A structure representing the result of the parser.
+	 */
+	static ResultType parseMarkovAutomatonTransitions(std::string const& filename);
+
+private:
+	/*
+	 * Performs the first pass on the input pointed to by the given buffer.
+	 *
+	 * @param buffer The buffer that cointains the input.
+	 * @param lineEndings The line endings that are to be used while parsing.
+	 * @return A structure representing the result of the first pass.
+	 */
+	static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings);
+
+	/*
+	 * Performs the second pass on the input pointed to by the given buffer with the information of the first pass.
+	 *
+	 * @param buffer The buffer that cointains the input.
+	 * @param lineEndings The line endings that are to be used while parsing.
+	 * @param firstPassResult The result of the first pass performed on the same input.
+	 * @return A structure representing the result of the second pass.
+	 */
+	static ResultType secondPass(char* buffer, SupportedLineEndingsEnum lineEndings, FirstPassResult const& firstPassResult);
+};
+
+} // namespace parser
+
 } // namespace storm
 
 #endif /* STORM_PARSER_MARKOVAUTOMATONSPARSETRANSITIONPARSER_H_ */
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index beabf456b..52058f4fc 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -40,7 +40,7 @@ NondeterministicModelParserResultContainer<double> parseNondeterministicModel(st
 	NondeterministicModelParserResultContainer<double> result(std::move(resultTransitionSystem), std::move(nondeterministicSparseTransitionParserResult.second), std::move(resultLabeling));
 	
 	if (stateRewardFile != "") {
-		result.stateRewards.reset(storm::parser::SparseStateRewardParser(stateCount, stateRewardFile));
+		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
 	}
 	if (transitionRewardFile != "") {
 		RewardMatrixInformationStruct* rewardMatrixInfo = new RewardMatrixInformationStruct(rowCount, stateCount, &result.rowMapping);
diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp
index 611afc9c6..67b2772d7 100644
--- a/src/parser/Parser.cpp
+++ b/src/parser/Parser.cpp
@@ -13,6 +13,10 @@
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;
 
+namespace storm {
+
+namespace parser {
+
 /*!
  *	Calls strtol() internally and checks if the new pointer is different
  *	from the original one, i.e. if str != *end. If they are the same, a
@@ -21,7 +25,7 @@ extern log4cplus::Logger logger;
  *	@param end New pointer will be written there
  *	@return Result of strtol()
  */
-uint_fast64_t storm::parser::checked_strtol(const char* str, char** end) {
+uint_fast64_t checked_strtol(const char* str, char** end) {
 	uint_fast64_t res = strtol(str, end, 10);
 	if (str == *end) {
 		LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number.");
@@ -39,7 +43,7 @@ uint_fast64_t storm::parser::checked_strtol(const char* str, char** end) {
  *	@param end New pointer will be written there
  *	@return Result of strtod()
  */
-double storm::parser::checked_strtod(const char* str, char** end) {
+double checked_strtod(const char* str, char** end) {
 	double res = strtod(str, end);
 	if (str == *end) {
 		LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number.");
@@ -53,7 +57,7 @@ double storm::parser::checked_strtod(const char* str, char** end) {
  *  @brief Tests whether the given file exists and is readable.
  *  @return True iff the file exists and is readable.
  */
-bool storm::parser::fileExistsAndIsReadable(const char* fileName) {
+bool fileExistsAndIsReadable(const char* fileName) {
 	std::ifstream fin(fileName);
 	bool returnValue = !fin.fail();
 	return returnValue;
@@ -62,8 +66,10 @@ bool storm::parser::fileExistsAndIsReadable(const char* fileName) {
 /*!
  * Skips all numbers, letters and special characters.
  * Returns a pointer to the first char that is a whitespace.
+ * @param buf The string buffer to operate on.
+ * @return A pointer to the first whitespace character.
  */
-char* storm::parser::skipWord(char* buf){
+char* skipWord(char* buf){
 	while((*buf != ' ') && (*buf != '\t') && (*buf != '\n') && (*buf != '\r')) buf++;
 	return buf;
 }
@@ -71,10 +77,10 @@ char* storm::parser::skipWord(char* buf){
 /*!
  *	Skips spaces, tabs, newlines and carriage returns. Returns a pointer
  *	to first char that is not a whitespace.
- *	@param buf String buffer
- *	@return	pointer to first non-whitespace character
+ *	@param buf The string buffer to operate on.
+ *	@return	A pointer to the first non-whitespace character.
  */
-char* storm::parser::trimWhitespaces(char* buf) {
+char* trimWhitespaces(char* buf) {
 	while ((*buf == ' ') || (*buf == '\t') || (*buf == '\n') || (*buf == '\r')) buf++;
 	return buf;
 }
@@ -82,7 +88,7 @@ char* storm::parser::trimWhitespaces(char* buf) {
 /*!
  * @briefs Analyzes the given file and tries to find out the used file endings.
  */
-storm::parser::SupportedLineEndingsEnum storm::parser::findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported) {
+SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported) {
 	MappedFile fileMap(fileName.c_str());
 	char* buf = nullptr;
 	char* const bufferEnd = fileMap.dataend;
@@ -91,11 +97,11 @@ storm::parser::SupportedLineEndingsEnum storm::parser::findUsedLineEndings(std::
 		if (*buf == '\r') {
 			// check for following \n
 			if (((buf + sizeof(char)) < bufferEnd) && (*(buf + sizeof(char)) == '\n')) {
-				return storm::parser::SupportedLineEndingsEnum::SlashRN; 
+				return SupportedLineEndingsEnum::SlashRN;
 			}
-			return storm::parser::SupportedLineEndingsEnum::SlashR; 
+			return SupportedLineEndingsEnum::SlashR;
 		} else if (*buf == '\n') {
-			return storm::parser::SupportedLineEndingsEnum::SlashN;
+			return SupportedLineEndingsEnum::SlashN;
 		}
 	}
 
@@ -105,25 +111,25 @@ storm::parser::SupportedLineEndingsEnum storm::parser::findUsedLineEndings(std::
 	}
 	LOG4CPLUS_WARN(logger, "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n");
 
-	return storm::parser::SupportedLineEndingsEnum::Unsupported;
+	return SupportedLineEndingsEnum::Unsupported;
 }
 
 /*!
  * @brief Encapsulates the usage of function @strchr to forward to the next line
  */
-char* storm::parser::forwardToNextLine(char* buffer, storm::parser::SupportedLineEndingsEnum lineEndings) {
+char* forwardToNextLine(char* buffer, SupportedLineEndingsEnum lineEndings) {
 	switch (lineEndings) {
-		case storm::parser::SupportedLineEndingsEnum::SlashN:
+		case SupportedLineEndingsEnum::SlashN:
 			return strchr(buffer, '\n') + 1;  
 			break;
-		case storm::parser::SupportedLineEndingsEnum::SlashR:
+		case SupportedLineEndingsEnum::SlashR:
 			return strchr(buffer, '\r') + 1;  
 			break;
-		case storm::parser::SupportedLineEndingsEnum::SlashRN:
+		case SupportedLineEndingsEnum::SlashRN:
 			return strchr(buffer, '\r') + 2;
 			break;
 		default:
-		case storm::parser::SupportedLineEndingsEnum::Unsupported:
+		case SupportedLineEndingsEnum::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
 			throw;
 			break;
@@ -136,26 +142,26 @@ char* storm::parser::forwardToNextLine(char* buffer, storm::parser::SupportedLin
  * @param targetBuffer The Target for the hint, must be at least 64 bytes long
  * @param buffer The Source Buffer from which the Model Hint will be read
  */
-void storm::parser::scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndingsEnum lineEndings) {
+void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, SupportedLineEndingsEnum lineEndings) {
 	if (targetBufferSize <= 4) {
 		throw;
 	}
 	switch (lineEndings) {
-		case storm::parser::SupportedLineEndingsEnum::SlashN:
+		case SupportedLineEndingsEnum::SlashN:
 #ifdef WINDOWS					
 			sscanf_s(buffer, "%60s\n", targetBuffer, targetBufferSize);
 #else
 			sscanf(buffer, "%60s\n", targetBuffer);
 #endif
 			break;
-		case storm::parser::SupportedLineEndingsEnum::SlashR:
+		case SupportedLineEndingsEnum::SlashR:
 #ifdef WINDOWS					
 			sscanf_s(buffer, "%60s\r", targetBuffer, sizeof(targetBufferSize));
 #else
 			sscanf(buffer, "%60s\r", targetBuffer);
 #endif
 			break;
-		case storm::parser::SupportedLineEndingsEnum::SlashRN:
+		case SupportedLineEndingsEnum::SlashRN:
 #ifdef WINDOWS					
 			sscanf_s(buffer, "%60s\r\n", targetBuffer, sizeof(targetBufferSize));
 #else
@@ -163,7 +169,7 @@ void storm::parser::scanForModelHint(char* targetBuffer, uint_fast64_t targetBuf
 #endif
 			break;
 		default:
-		case storm::parser::SupportedLineEndingsEnum::Unsupported:
+		case SupportedLineEndingsEnum::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
 			throw;
 			break;
@@ -173,9 +179,9 @@ void storm::parser::scanForModelHint(char* targetBuffer, uint_fast64_t targetBuf
 /*!
  * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
  */
-void storm::parser::getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndingsEnum lineEndings) {
+void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, SupportedLineEndingsEnum lineEndings) {
 	if (targetBufferSize < 5) {
-		LOG4CPLUS_ERROR(logger, "storm::parser::getMatchingSeparatorString: The passed Target Buffer is too small.");
+		LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed Target Buffer is too small.");
 		throw;
 	}
 	switch (lineEndings) {
@@ -209,7 +215,7 @@ void storm::parser::getMatchingSeparatorString(char* targetBuffer, uint_fast64_t
 		default:
 		case SupportedLineEndingsEnum::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
-			LOG4CPLUS_ERROR(logger, "storm::parser::getMatchingSeparatorString: The passed lineEndings were Unsupported. Check your input file.");
+			LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed lineEndings were Unsupported. Check your input file.");
 			throw;
 			break;
 	}
@@ -221,7 +227,7 @@ void storm::parser::getMatchingSeparatorString(char* targetBuffer, uint_fast64_t
  *	and a log entry is written.
  *	@param filename file to be opened
  */
-storm::parser::MappedFile::MappedFile(const char* filename) {
+MappedFile::MappedFile(const char* filename) {
 #if defined LINUX || defined MACOSX
 	/*
 	 *	Do file mapping for reasonable systems.
@@ -233,20 +239,20 @@ storm::parser::MappedFile::MappedFile(const char* filename) {
 	if (stat64(filename, &(this->st)) != 0) {
 #endif
 		LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): Probably, this file does not exist.");
-		throw exceptions::FileIoException() << "storm::parser::MappedFile Error in stat(): Probably, this file does not exist.";
+		throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist.";
 	}
 	this->file = open(filename, O_RDONLY);
 
 	if (this->file < 0) {
 		LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): Probably, we may not read this file.");
-		throw exceptions::FileIoException() << "storm::parser::MappedFile Error in open(): Probably, we may not read this file.";
+		throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file.";
 	}
 
 	this->data = reinterpret_cast<char*>(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0));
 	if (this->data == reinterpret_cast<char*>(-1)) {
 		close(this->file);
 		LOG4CPLUS_ERROR(logger, "Error in mmap(" << filename << "): " << std::strerror(errno));
-		throw exceptions::FileIoException() << "storm::parser::MappedFile Error in mmap(): " << std::strerror(errno);
+		throw exceptions::FileIoException() << "MappedFile Error in mmap(): " << std::strerror(errno);
 	}
 	this->dataend = this->data + this->st.st_size;
 #elif defined WINDOWS
@@ -256,20 +262,20 @@ storm::parser::MappedFile::MappedFile(const char* filename) {
 	 */
 	if (_stat64(filename, &(this->st)) != 0) {
 		LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist.");
-		throw exceptions::FileIoException("storm::parser::MappedFile Error in stat(): Probably, this file does not exist.");
+		throw exceptions::FileIoException("MappedFile Error in stat(): Probably, this file does not exist.");
 	}
 
 	this->file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 	if (this->file == INVALID_HANDLE_VALUE) {
 		LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << "): Probably, we may not read this file.");
-		throw exceptions::FileIoException("storm::parser::MappedFile Error in CreateFileA(): Probably, we may not read this file.");
+		throw exceptions::FileIoException("MappedFile Error in CreateFileA(): Probably, we may not read this file.");
 	}
 
 	this->mapping = CreateFileMappingA(this->file, NULL, PAGE_READONLY, (DWORD)(st.st_size >> 32), (DWORD)st.st_size, NULL);
 	if (this->mapping == NULL) {
 		CloseHandle(this->file);
 		LOG4CPLUS_ERROR(logger, "Error in CreateFileMappingA(" << filename << ").");
-		throw exceptions::FileIoException("storm::parser::MappedFile Error in CreateFileMappingA().");
+		throw exceptions::FileIoException("MappedFile Error in CreateFileMappingA().");
 	}
 
 	this->data = static_cast<char*>(MapViewOfFile(this->mapping, FILE_MAP_READ, 0, 0, this->st.st_size));
@@ -277,7 +283,7 @@ storm::parser::MappedFile::MappedFile(const char* filename) {
 		CloseHandle(this->mapping);
 		CloseHandle(this->file);
 		LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ").");
-		throw exceptions::FileIoException("storm::parser::MappedFile Error in MapViewOfFile().");
+		throw exceptions::FileIoException("MappedFile Error in MapViewOfFile().");
 	}
 	this->dataend = this->data + this->st.st_size;
 #endif
@@ -286,7 +292,7 @@ storm::parser::MappedFile::MappedFile(const char* filename) {
 /*!
  *	Will unmap the data and close the file.
  */
-storm::parser::MappedFile::~MappedFile() {
+MappedFile::~MappedFile() {
 #if defined LINUX || defined MACOSX
 	munmap(this->data, this->st.st_size);
 	close(this->file);
@@ -295,3 +301,7 @@ storm::parser::MappedFile::~MappedFile() {
 	CloseHandle(this->file);
 #endif
 }
+
+} // namespace parser
+
+} // namespace storm
diff --git a/src/parser/Parser.h b/src/parser/Parser.h
index 94e0cbb58..3fee43b98 100644
--- a/src/parser/Parser.h
+++ b/src/parser/Parser.h
@@ -34,146 +34,147 @@ namespace storm {
  */
 namespace parser {
 
-	struct RewardMatrixInformationStruct {
-		RewardMatrixInformationStruct() : rowCount(0), columnCount(0), nondeterministicChoiceIndices(nullptr) {
-			// Intentionally left empty.
-		}
+struct RewardMatrixInformationStruct {
+	RewardMatrixInformationStruct() : rowCount(0), columnCount(0), nondeterministicChoiceIndices(nullptr) {
+		// Intentionally left empty.
+	}
 
-		RewardMatrixInformationStruct(uint_fast64_t rowCount, uint_fast64_t columnCount, std::vector<uint_fast64_t> const * const nondeterministicChoiceIndices)
-		: rowCount(rowCount), columnCount(columnCount), nondeterministicChoiceIndices(nondeterministicChoiceIndices) {
-			// Intentionally left empty.
-		}
+	RewardMatrixInformationStruct(uint_fast64_t rowCount, uint_fast64_t columnCount, std::vector<uint_fast64_t> const * const nondeterministicChoiceIndices)
+	: rowCount(rowCount), columnCount(columnCount), nondeterministicChoiceIndices(nondeterministicChoiceIndices) {
+		// Intentionally left empty.
+	}
 
-		uint_fast64_t rowCount;
-		uint_fast64_t columnCount;
-		std::vector<uint_fast64_t> const * const nondeterministicChoiceIndices;
-	};
+	uint_fast64_t rowCount;
+	uint_fast64_t columnCount;
+	std::vector<uint_fast64_t> const * const nondeterministicChoiceIndices;
+};
 
-	/*!
-	 *	@brief Opens a file and maps it to memory providing a char*
-	 *	containing the file content.
-	 * 
-	 *	This class is a very simple interface to read files efficiently.
-	 *	The given file is opened and mapped to memory using mmap().
-	 *	The public member data is a pointer to the actual file content.
-	 *	Using this method, the kernel will take care of all buffering. This is
-	 *	most probably much more efficient than doing this manually.
-	 */
+/*!
+ *	@brief Opens a file and maps it to memory providing a char*
+ *	containing the file content.
+ *
+ *	This class is a very simple interface to read files efficiently.
+ *	The given file is opened and mapped to memory using mmap().
+ *	The public member data is a pointer to the actual file content.
+ *	Using this method, the kernel will take care of all buffering. This is
+ *	most probably much more efficient than doing this manually.
+ */
 
 #if !defined LINUX && !defined MACOSX && !defined WINDOWS
-	#error Platform not supported
+#error Platform not supported
 #endif
 
-	class MappedFile {
-		private:
+class MappedFile {
+	private:
 #if defined LINUX || defined MACOSX
-			/*!
-			 *	@brief file descriptor obtained by open().
-			 */
-			int file;
+		/*!
+		 *	@brief file descriptor obtained by open().
+		 */
+		int file;
 #elif defined WINDOWS
-			HANDLE file;
-			HANDLE mapping;
+		HANDLE file;
+		HANDLE mapping;
 #endif
 
 #if defined LINUX
-			/*!
-			 *	@brief stat information about the file.
-			 */
-			struct stat64 st;
+		/*!
+		 *	@brief stat information about the file.
+		 */
+		struct stat64 st;
 #elif defined MACOSX
-			/*!
-			 *	@brief stat information about the file.
-			 */
-			struct stat st;
+		/*!
+		 *	@brief stat information about the file.
+		 */
+		struct stat st;
 #elif defined WINDOWS
-			/*!
-			 *	@brief stat information about the file.
-			 */
-			struct __stat64 st;
+		/*!
+		 *	@brief stat information about the file.
+		 */
+		struct __stat64 st;
 #endif
 
-		public:
-			/*!
-			 *	@brief pointer to actual file content.
-			 */
-			char* data;
-			
-			/*!
-			 *	@brief pointer to end of file content.
-			 */
-			char* dataend;
-		
+	public:
 		/*!
-		 *	@brief Constructor of MappedFile.
+		 *	@brief pointer to actual file content.
 		 */
-		MappedFile(const char* filename);
+		char* data;
 		
 		/*!
-		 *	@brief Destructor of MappedFile.
+		 *	@brief pointer to end of file content.
 		 */
-		~MappedFile();
-	};
+		char* dataend;
 
 	/*!
-	 *	@brief Parses integer and checks, if something has been parsed.
+	 *	@brief Constructor of MappedFile.
 	 */
-	uint_fast64_t checked_strtol(const char* str, char** end);
-
-	/*!
-	 *	@brief Parses floating point and checks, if something has been parsed.
-	 */
-	double checked_strtod(const char* str, char** end);
+	MappedFile(const char* filename);
 	
 	/*!
-	 * @brief Skips all non whitespace characters until the next whitespace.
+	 *	@brief Destructor of MappedFile.
 	 */
-	char* skipWord(char* buf);
+	~MappedFile();
+};
 
-	/*!
-	 *	@brief Skips common whitespaces in a string.
-	 */
-	char* trimWhitespaces(char* buf);
+/*!
+ *	@brief Parses integer and checks, if something has been parsed.
+ */
+uint_fast64_t checked_strtol(const char* str, char** end);
 
-	/*!
-	 *  @brief Tests whether the given file exists and is readable.
-	 */
-	bool fileExistsAndIsReadable(const char* fileName);
+/*!
+ *	@brief Parses floating point and checks, if something has been parsed.
+ */
+double checked_strtod(const char* str, char** end);
 
-	/*!
-	 * @brief Enum Class Type containing all supported file endings.
-	 */
-	enum class SupportedLineEndingsEnum : unsigned short {
-		Unsupported = 0,
-		SlashR,
-		SlashN,
-		SlashRN
-	};
+/*!
+ * @brief Skips all non whitespace characters until the next whitespace.
+ */
+char* skipWord(char* buf);
 
-	/*!
-	 * @briefs Analyzes the given file and tries to find out the used line endings.
-	 */
-	storm::parser::SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false);
+/*!
+ *	@brief Skips common whitespaces in a string.
+ */
+char* trimWhitespaces(char* buf);
 
-	/*!
-	 * @brief Encapsulates the usage of function @strchr to forward to the next line
-	 */
-	char* forwardToNextLine(char* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+/*!
+ *  @brief Tests whether the given file exists and is readable.
+ */
+bool fileExistsAndIsReadable(const char* fileName);
 
-	/*!
-	 * @brief Encapsulates the usage of function @sscanf to scan for the model type hint
-	 * @param targetBuffer The Target for the hint, should be at least 64 bytes long
-	 * @param buffer The Source Buffer from which the Model Hint will be read
+/*!
+ * @brief Enum Class Type containing all supported file endings.
+ */
+enum class SupportedLineEndingsEnum : unsigned short {
+	Unsupported = 0,
+	SlashR,
+	SlashN,
+	SlashRN
+};
 
-	 */
-	void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+/*!
+ * @briefs Analyzes the given file and tries to find out the used line endings.
+ */
+storm::parser::SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false);
 
-	/*!
-	 * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
-	 */
-	void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndingsEnum lineEndings);
+/*!
+ * @brief Encapsulates the usage of function @strchr to forward to the next line
+ */
+char* forwardToNextLine(char* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+
+/*!
+ * @brief Encapsulates the usage of function @sscanf to scan for the model type hint
+ * @param targetBuffer The Target for the hint, should be at least 64 bytes long
+ * @param buffer The Source Buffer from which the Model Hint will be read
+
+ */
+void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+
+/*!
+ * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
+ */
+void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndingsEnum lineEndings);
 
 } // namespace parser
+
 } // namespace storm
 
 #endif /* STORM_PARSER_PARSER_H_ */
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index a5d43e024..9a4e34be6 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -7,29 +7,18 @@
 
 #include "src/parser/SparseStateRewardParser.h"
 
-#include <errno.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <locale.h>
 #include <iostream>
-#include <cstdlib>
-#include <cstdio>
-#include <cstring>
-#include <string>
-#include <vector>
-#include <clocale>
 
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
-#include "src/utility/OsDetection.h"
+#include "src/parser/Parser.h"
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;
 
 namespace storm {
-namespace parser {
 
+namespace parser {
 
 /*!
  *	Reads a state reward file and puts the result in a state reward vector.
@@ -38,7 +27,7 @@ namespace parser {
  *	@param filename The filename of the state reward file.
  *	@return The created state reward vector.
  */
-std::vector<double> SparseStateRewardParser(uint_fast64_t stateCount, std::string const & filename) {
+std::vector<double> SparseStateRewardParser::parseSparseStateReward(uint_fast64_t stateCount, std::string const & filename) {
 	// Open file.
 	if (!fileExistsAndIsReadable(filename.c_str())) {
 		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
@@ -51,28 +40,27 @@ std::vector<double> SparseStateRewardParser(uint_fast64_t stateCount, std::strin
 	// Create state reward vector with given state count.
 	std::vector<double> stateRewards(stateCount);
 
-	{
-		// Now parse state reward assignments.
-		uint_fast64_t state;
-		double reward;
+	// Now parse state reward assignments.
+	uint_fast64_t state;
+	double reward;
 
-		// Iterate over states.
-		while (buf[0] != '\0') {
-			// Parse state number and reward value.
-			state = checked_strtol(buf, &buf);
-			reward = checked_strtod(buf, &buf);
-			if (reward < 0.0) {
-				LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\".");
-				throw storm::exceptions::WrongFormatException() << "State reward file specifies illegal reward value.";
-			}
+	// Iterate over states.
+	while (buf[0] != '\0') {
+		// Parse state number and reward value.
+		state = checked_strtol(buf, &buf);
+		reward = checked_strtod(buf, &buf);
+		if (reward < 0.0) {
+			LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\".");
+			throw storm::exceptions::WrongFormatException() << "State reward file specifies illegal reward value.";
+		}
 
-			stateRewards[state] = reward;
+		stateRewards[state] = reward;
 
-			buf = trimWhitespaces(buf);
-		}
+		buf = trimWhitespaces(buf);
 	}
 	return stateRewards;
 }
 
 }  // namespace parser
+
 }  // namespace storm
diff --git a/src/parser/SparseStateRewardParser.h b/src/parser/SparseStateRewardParser.h
index 03f26c902..2efe0a937 100644
--- a/src/parser/SparseStateRewardParser.h
+++ b/src/parser/SparseStateRewardParser.h
@@ -2,18 +2,25 @@
 #define STORM_PARSER_SPARSESTATEREWARDPARSER_H_
 
 #include <cstdint>
-#include "src/parser/Parser.h"
-#include <memory>
 #include <vector>
+#include <string>
 
 namespace storm {
 
 namespace parser {
 
 /*!
- *	@brief Load state reward file and return vector of state rewards.
+ * A class providing the functionality to parse a the state rewards of a model.
  */
-std::vector<double> SparseStateRewardParser(uint_fast64_t stateCount, std::string const &filename);
+class SparseStateRewardParser {
+public:
+
+	/*!
+	 *	@brief Load state reward file and return vector of state rewards.
+	 */
+	static std::vector<double> parseSparseStateReward(uint_fast64_t stateCount, std::string const &filename);
+
+};
 
 } // namespace parser
 
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index 93b02b3d2..a5803d119 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -9,8 +9,13 @@
 #include "storm-config.h"
 #include "src/settings/Settings.h"
 
+#include <cmath>
+#include <vector>
+
 #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
+#include "src/parser/SparseStateRewardParser.h"
 #include "src/parser/Parser.h"
+#include "src/parser/MarkovAutomatonParser.h"
 
 #define STATE_COUNT 6
 #define CHOICE_COUNT 7
@@ -176,3 +181,37 @@ TEST(MarkovAutomatonSparseTransitionParserTest, DeadlockTest) {
 		storm::settings::Settings::getInstance()->set("fixDeadlocks");
 	}
 }*/
+
+double round(double val, int precision)
+{
+    std::stringstream s;
+    s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
+    s >> val;
+    return val;
+}
+
+TEST(SparseStateRewardParserTest, BasicParseTest) {
+
+	// Get the parsing result.
+	std::vector<double> result = storm::parser::SparseStateRewardParser::parseSparseStateReward(100, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_basic.state.rew");
+
+	// Now test if the correct value were parsed.
+	for(int i = 0; i < 100; i++) {
+		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
+	}
+}
+
+TEST(MarkovAutomatonParserTest, BasicParseTest) {
+
+	// Get the parsing result.
+	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input_01.state.rew", "");
+
+	// Test sizes and counts.
+	ASSERT_EQ(result.getNumberOfStates(), STATE_COUNT);
+	ASSERT_EQ(result.getNumberOfChoices(), CHOICE_COUNT);
+	ASSERT_EQ(result.getNumberOfTransitions(), 12);
+
+	// Test
+	std::vector<double> rates = result.getExitRates();
+	ASSERT_EQ(rates[0], 2);
+}

From 3598b7195ed2f3f2aa78a0f0f12b294574ab6e3e Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Sat, 14 Dec 2013 16:45:24 +0100
Subject: [PATCH 004/147] Refactored the DeterministicSparseTransitionParser.

Former-commit-id: 9012aadd9deccf259c05635b550556f460dcb614
---
 src/parser/DeterministicModelParser.cpp       |   7 +-
 .../DeterministicSparseTransitionParser.cpp   | 315 ++++++++++--------
 .../DeterministicSparseTransitionParser.h     |  52 ++-
 .../MarkovAutomatonSparseTransitionParser.cpp |   7 +-
 test/functional/parser/ReadTraFileTest.cpp    |  10 +-
 5 files changed, 244 insertions(+), 147 deletions(-)

diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index 1b5ec197c..44e484bc0 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -29,7 +29,7 @@ namespace parser {
 DeterministicModelParserResultContainer<double> parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
 																		std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-	storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(storm::parser::DeterministicSparseTransitionParser(transitionSystemFile)));
+	storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionSystemFile)));
 
 	uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
 	uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
@@ -42,9 +42,8 @@ DeterministicModelParserResultContainer<double> parseDeterministicModel(std::str
 		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
 	}
 	if (transitionRewardFile != "") {
-		RewardMatrixInformationStruct* rewardMatrixInfo = new RewardMatrixInformationStruct(rowCount, stateCount, nullptr);
-		result.transitionRewards.reset(std::move(storm::parser::DeterministicSparseTransitionParser(transitionRewardFile, false, rewardMatrixInfo)));
-		delete rewardMatrixInfo;
+		RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, nullptr);
+		result.transitionRewards.reset(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo)));
 	}
 
 	return result;
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 2b21bcba5..76cd49af5 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -30,6 +30,7 @@
 extern log4cplus::Logger logger;
 
 namespace storm {
+
 namespace parser {
 
 /*!
@@ -44,43 +45,36 @@ namespace parser {
  *	@param buf Data to scan. Is expected to be some char array.
  *	@param maxnode Is set to highest id of all nodes.
  */
-uint_fast64_t firstPass(char* buf, SupportedLineEndingsEnum lineEndings, uint_fast64_t& maxnode, RewardMatrixInformationStruct* rewardMatrixInformation) {
-	bool isRewardMatrix = rewardMatrixInformation != nullptr;
-
-	uint_fast64_t nonZeroEntryCount = 0;
+DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing) {
+	DeterministicSparseTransitionParser::FirstPassResult result;
 
-	/*
-	 *	Check file header and extract number of transitions.
-	 */
-	if (!isRewardMatrix) {
-		// skip format hint
+	// Skip the format hint if it is there.
+	buf = trimWhitespaces(buf);
+	if(buf[0] != '0') {
 		buf = storm::parser::forwardToNextLine(buf, lineEndings);
 	}
 
-	/*
-	 * Check all transitions for non-zero diagonal entries and deadlock states.
-	 */
-	int_fast64_t lastRow = -1;
-	uint_fast64_t row, col;
-	uint_fast64_t readTransitionCount = 0;
+	 // Check all transitions for non-zero diagonal entries and deadlock states.
+	uint_fast64_t row, col, lastRow = 0;
 	bool rowHadDiagonalEntry = false;
-	double val;
-	maxnode = 0;
 	while (buf[0] != '\0') {
-		/*
-		 *      Read row and column.
-		 */
+
+		// Read the transition..
 		row = checked_strtol(buf, &buf);
 		col = checked_strtol(buf, &buf);
-
-		if (!isRewardMatrix) {
-			if (lastRow != (int_fast64_t)row) {
-				if ((lastRow != -1) && (!rowHadDiagonalEntry)) {
-					++nonZeroEntryCount;
-					rowHadDiagonalEntry = true;
+		// The actual read value is not needed here.
+		checked_strtod(buf, &buf);
+
+		// Compensate for missing diagonal entries if desired.
+		if (insertDiagonalEntriesIfMissing) {
+			if (lastRow != row) {
+				if(!rowHadDiagonalEntry) {
+					++result.numberOfNonzeroEntries;
 				}
-				for (uint_fast64_t skippedRow = (uint_fast64_t)(lastRow + 1); skippedRow < row; ++skippedRow) {
-					++nonZeroEntryCount;
+
+				// Compensate for missing rows.
+				for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
+					++result.numberOfNonzeroEntries;
 				}
 				lastRow = row;
 				rowHadDiagonalEntry = false;
@@ -88,41 +82,36 @@ uint_fast64_t firstPass(char* buf, SupportedLineEndingsEnum lineEndings, uint_fa
 
 			if (col == row) {
 				rowHadDiagonalEntry = true;
-			} else if (col > row && !rowHadDiagonalEntry) {
+			}
+
+			if (col > row && !rowHadDiagonalEntry) {
 				rowHadDiagonalEntry = true;
-				++nonZeroEntryCount;
+				++result.numberOfNonzeroEntries;
 			}
 		}
 
-		/*
-		 *      Check if one is larger than the current maximum id.
-		 */
-		if (row > maxnode) maxnode = row;
-		if (col > maxnode) maxnode = col;
+		// Check if a higher state id was found.
+		if (row > result.highestStateIndex) result.highestStateIndex = row;
+		if (col > result.highestStateIndex) result.highestStateIndex = col;
 
-		/*
-		 *      Read probability of this transition.
-		 *      Check, if the value is a probability, i.e. if it is between 0 and 1.
-		 */
-		val = checked_strtod(buf, &buf);
-		if ((val < 0.0) || (val > 1.0)) {
-			LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
-			return 0;
-		}
-		++nonZeroEntryCount;
-		++readTransitionCount;
+		++result.numberOfNonzeroEntries;
 		buf = trimWhitespaces(buf);
 	}
 
-	if (!rowHadDiagonalEntry && !isRewardMatrix) {
-	++nonZeroEntryCount;
+	if(insertDiagonalEntriesIfMissing) {
+		if (!rowHadDiagonalEntry) {
+			++result.numberOfNonzeroEntries;
+		}
+
+		//Compensate for missing rows at the end of the file.
+		for (uint_fast64_t skippedRow = (uint_fast64_t)(lastRow + 1); skippedRow <= result.highestStateIndex; ++skippedRow) {
+			++result.numberOfNonzeroEntries;
+		}
 	}
 
-	return nonZeroEntryCount;
+	return result;
 }
 
-
-
 /*!
  *	Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
  *
@@ -131,122 +120,99 @@ uint_fast64_t firstPass(char* buf, SupportedLineEndingsEnum lineEndings, uint_fa
  *	@return a pointer to the created sparse matrix.
  */
 
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser(std::string const& filename, bool insertDiagonalEntriesIfMissing, RewardMatrixInformationStruct* rewardMatrixInformation) {
-	/*
-	 *	Enforce locale where decimal point is '.'.
-	 */
-	setlocale(LC_NUMERIC, "C");
+storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing) {
 
-	bool isRewardMatrix = rewardMatrixInformation != nullptr;
+	// Enforce locale where decimal point is '.'.
+	setlocale(LC_NUMERIC, "C");
 
 	if (!fileExistsAndIsReadable(filename.c_str())) {
 		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
 		throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
 	}
 
-	/*
-	 *	Find out about the used line endings.
-	 */
+	// Find out about the used line endings.
 	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
 
-	/*
-	 *	Open file.
-	 */
+	// Open file.
 	MappedFile file(filename.c_str());
 	char* buf = file.data;
 
-	/*
-	 *	Perform first pass, i.e. count entries that are not zero.
-	 */
-	uint_fast64_t maxStateId;
-	uint_fast64_t nonZeroEntryCount = firstPass(file.data, lineEndings, maxStateId, rewardMatrixInformation);
+	// Perform first pass, i.e. count entries that are not zero.
 
-	LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << nonZeroEntryCount << " NonZeros.");
+	DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, insertDiagonalEntriesIfMissing);
 
-	/*
-	 *	If first pass returned zero, the file format was wrong.
-	 */
-	if (nonZeroEntryCount == 0) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format.");
+	LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
+
+	// If first pass returned zero, the file format was wrong.
+	if (firstPass.numberOfNonzeroEntries == 0) {
+		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
 		throw storm::exceptions::WrongFormatException();
 	}
 
-	/*
-	 *	Perform second pass-
-	 *	
-	 *	From here on, we already know that the file header is correct.
-	 */
-
-	/*
-	 *	Read file header, extract number of states.
-	 */
-	if (!isRewardMatrix) {
-		// skip format hint
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
-	}
+	// Perform second pass.
 
-	// If the matrix that is being parsed is a reward matrix, it should match the size of the
-	// transition matrix.
-	if (isRewardMatrix) {
-		if (maxStateId + 1 > rewardMatrixInformation->rowCount || maxStateId + 1 > rewardMatrixInformation->columnCount) {
-			LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
-			throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
-		} else {
-			maxStateId = rewardMatrixInformation->rowCount - 1;
-		}
+	// Skip the format hint if it is there.
+	buf = trimWhitespaces(buf);
+	if(buf[0] != '0') {
+		buf = storm::parser::forwardToNextLine(buf, lineEndings);
 	}
 
-	/*
-	 *	Creating matrix here.
-	 *	The number of non-zero elements is computed by firstPass().
-	 */
-	LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << (maxStateId+1) << " x " << (maxStateId+1) << ".");
-	storm::storage::SparseMatrix<double> resultMatrix(maxStateId + 1);
-	resultMatrix.initialize(nonZeroEntryCount);
+	// Creating matrix here.
+	// The number of non-zero elements is computed by firstPass().
+	LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
+	storm::storage::SparseMatrix<double> resultMatrix(firstPass.highestStateIndex + 1);
+	resultMatrix.initialize(firstPass.numberOfNonzeroEntries);
 	if (!resultMatrix.isInitialized()) {
-		LOG4CPLUS_ERROR(logger, "Could not create matrix of size " << (maxStateId+1) << " x " << (maxStateId+1) << ".");
+		LOG4CPLUS_ERROR(logger, "Could not create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
 		throw std::bad_alloc();
 	}
 
-	int_fast64_t row, lastRow = -1, col;
+	uint_fast64_t row, col, lastRow = 0;
 	double val;
 	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 	bool hadDeadlocks = false;
 	bool rowHadDiagonalEntry = false;
 
-	/*
-	 *	Read all transitions from file. Note that we assume that the
-	 *	transitions are listed in canonical order, otherwise this will not
-	 *	work, i.e. the values in the matrix will be at wrong places.
-	 */
+
+	// Read all transitions from file. Note that we assume that the
+	// transitions are listed in canonical order, otherwise this will not
+	// work, i.e. the values in the matrix will be at wrong places.
 	while (buf[0] != '\0') {
-		/*
-		 *	Read row, col and value.
-		 */
+
+		// Read next transition.
 		row = checked_strtol(buf, &buf);
 		col = checked_strtol(buf, &buf);
 		val = checked_strtod(buf, &buf);
 
+		// Read probability of this transition.
+		// Check, if the value is a probability, i.e. if it is between 0 and 1.
+		if ((val < 0.0) || (val > 1.0)) {
+			LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
+			throw storm::exceptions::WrongFormatException();
+		}
+
+		// Test if we moved to a new row.
+		// Handle all incomplete or skipped rows.
 		if (lastRow != row) {
-			if ((lastRow != -1) && (!rowHadDiagonalEntry)) {
-				if (insertDiagonalEntriesIfMissing && !isRewardMatrix) {
+			if (!rowHadDiagonalEntry) {
+				if (insertDiagonalEntriesIfMissing) {
 					resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constGetZero<double>());
 					LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
-				} else if (!isRewardMatrix) {
+				} else {
 					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
 				}
-				// No increment for lastRow
+				// No increment for lastRow.
 				rowHadDiagonalEntry = true;
 			}
-			for (int_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
+			for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
 				hadDeadlocks = true;
-				if (fixDeadlocks && !isRewardMatrix) {
+				if (fixDeadlocks) {
 					resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constGetOne<double>());
 					rowHadDiagonalEntry = true;
 					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
-				} else if (!isRewardMatrix) {
+				} else {
 					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
-					// FIXME Why no exception at this point? This will break the App.
+					// Before throwing the appropriate exception we will give notice of all deadlock states.
 				}
 			}
 			lastRow = row;
@@ -255,14 +221,16 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser(std::st
 
 		if (col == row) {
 			rowHadDiagonalEntry = true;
-		} else if (col > row && !rowHadDiagonalEntry) {
-			rowHadDiagonalEntry = true;
-			if (insertDiagonalEntriesIfMissing && !isRewardMatrix) {
+		}
+
+		if (col > row && !rowHadDiagonalEntry) {
+			if (insertDiagonalEntriesIfMissing) {
 				resultMatrix.addNextValue(row, row, storm::utility::constGetZero<double>());
 				LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
-			} else if (!isRewardMatrix) {
+			} else {
 				LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
 			}
+			rowHadDiagonalEntry = true;
 		}
 
 		resultMatrix.addNextValue(row, col, val);
@@ -270,23 +238,110 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser(std::st
 	}
 
 	if (!rowHadDiagonalEntry) {
-		if (insertDiagonalEntriesIfMissing && !isRewardMatrix) {
+		if (insertDiagonalEntriesIfMissing) {
 			resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constGetZero<double>());
 			LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
-		} else if (!isRewardMatrix) {
+		} else {
 			LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
 		}
 	}
 
+	// If we encountered deadlock and did not fix them, now is the time to throw the exception.
 	if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
 
-	/*
-	 *	Finalize Matrix.
-	 */	
+	// Finalize Matrix.
+	resultMatrix.finalize();
+
+	return resultMatrix;
+}
+
+/*!
+ *	Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
+ *
+ *	Matrices created with this method have to be freed with the delete operator.
+ *	@param filename input .tra file's name.
+ *	@return a pointer to the created sparse matrix.
+ */
+
+storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+	// Enforce locale where decimal point is '.'.
+	setlocale(LC_NUMERIC, "C");
+
+	if (!fileExistsAndIsReadable(filename.c_str())) {
+		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+		throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
+	}
+
+	// Find out about the used line endings.
+	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+
+	// Open file.
+	MappedFile file(filename.c_str());
+	char* buf = file.data;
+
+	// Perform first pass, i.e. count entries that are not zero.
+
+	DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, false);
+
+	LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
+
+	// If first pass returned zero, the file format was wrong.
+	if (firstPass.numberOfNonzeroEntries == 0) {
+		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
+		throw storm::exceptions::WrongFormatException();
+	}
+
+	// Perform second pass.
+
+	// Skip the format hint if it is there.
+	buf = trimWhitespaces(buf);
+	if(buf[0] != '0') {
+		buf = storm::parser::forwardToNextLine(buf, lineEndings);
+	}
+
+	// The reward matrix should match the size of the transition matrix.
+	if (firstPass.highestStateIndex + 1 > rewardMatrixInformation.rowCount || firstPass.highestStateIndex + 1 > rewardMatrixInformation.columnCount) {
+		LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
+		throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
+	} else {
+		// If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
+		firstPass.highestStateIndex = rewardMatrixInformation.rowCount - 1;
+	}
+
+
+	// Creating matrix here.
+	// The number of non-zero elements is computed by firstPass().
+	LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
+	storm::storage::SparseMatrix<double> resultMatrix(firstPass.highestStateIndex + 1);
+	resultMatrix.initialize(firstPass.numberOfNonzeroEntries);
+	if (!resultMatrix.isInitialized()) {
+		LOG4CPLUS_ERROR(logger, "Could not create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
+		throw std::bad_alloc();
+	}
+
+	uint_fast64_t row, col;
+	double val;
+
+	// Read all transitions from file. Note that we assume that the
+	// transitions are listed in canonical order, otherwise this will not
+	// work, i.e. the values in the matrix will be at wrong places.
+	while (buf[0] != '\0') {
+
+		// Read next transition.
+		row = checked_strtol(buf, &buf);
+		col = checked_strtol(buf, &buf);
+		val = checked_strtod(buf, &buf);
+
+		resultMatrix.addNextValue(row, col, val);
+		buf = trimWhitespaces(buf);
+	}
+
+	// Finalize Matrix.
 	resultMatrix.finalize();
 
 	return resultMatrix;
 }
 
 }  // namespace parser
+
 }  // namespace storm
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index cca8bf9e0..7fcd62a1f 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -9,15 +9,55 @@
 #include <memory>
 
 namespace storm {
+
 namespace parser {
-	
-/*!
- *	@brief	Load a deterministic transition system from file and create a
- *	sparse adjacency matrix whose entries represent the weights of the edges
- */
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser(std::string const& filename, bool insertDiagonalEntriesIfMissing = true, RewardMatrixInformationStruct* rewardMatrixInformation = nullptr);
+
+class DeterministicSparseTransitionParser {
+public:
+	/*
+	 * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model and the highest state index.
+	 */
+	struct FirstPassResult {
+
+		FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0) {
+			// Intentionally left empty.
+		}
+
+		// The total number of non-zero entries of the model.
+		uint_fast64_t numberOfNonzeroEntries;
+
+		// The highest state index that appears in the model.
+		uint_fast64_t highestStateIndex;
+	};
+
+	/*!
+	 *	@brief	Load a deterministic transition system from file and create a
+	 *	sparse adjacency matrix whose entries represent the weights of the edges
+	 */
+	static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing = true);
+
+	/*!
+	 *	@brief	Load the transition rewards for a deterministic transition system from file and create a
+	 *	sparse adjacency matrix whose entries represent the rewards of the respective transitions.
+	 */
+	static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation);
+
+private:
+
+	/*
+	 * Performs the first pass on the input pointed to by the given buffer.
+	 *
+	 * @param buffer The buffer that cointains the input.
+	 * @param lineEndings The line endings that are to be used while parsing.
+	 * @param insertDiagonalEntriesIfMissing Flag determining whether
+	 * @return A structure representing the result of the first pass.
+	 */
+	static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing = true);
+
+};
 
 } // namespace parser
+
 } // namespace storm
 
 #endif /* STORM_PARSER_TRAPARSER_H_ */
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 94145fb66..ce89951d9 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -11,8 +11,11 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 
 	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 
-	// Skip the format hint.
-	buf = storm::parser::forwardToNextLine(buf, lineEndings);
+	// Skip the format hint if it is there.
+	buf = trimWhitespaces(buf);
+	if(buf[0] != '0') {
+		buf = storm::parser::forwardToNextLine(buf, lineEndings);
+	}
 
 	// Now read the transitions.
 	int_fast64_t source, target = -1;
diff --git a/test/functional/parser/ReadTraFileTest.cpp b/test/functional/parser/ReadTraFileTest.cpp
index e6ff86456..7cf6c1432 100644
--- a/test/functional/parser/ReadTraFileTest.cpp
+++ b/test/functional/parser/ReadTraFileTest.cpp
@@ -14,13 +14,13 @@
 
 TEST(ReadTraFileTest, NonExistingFileTest) {
    //No matter what happens, please don't create a file with the name "nonExistingFile.not"! :-)
-   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
 }
 
 /* The following test case is based on one of the original MRMC test cases
  */
 TEST(ReadTraFileTest, ParseFileTest1) {
-	storm::storage::SparseMatrix<double> result = storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/csl_general_input_01.tra");
+	storm::storage::SparseMatrix<double> result = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/csl_general_input_01.tra");
 
 	double val = 0.0;
 	ASSERT_TRUE(result.getValue(0, 0, &val));
@@ -65,13 +65,13 @@ TEST(ReadTraFileTest, ParseFileTest1) {
 }
 
 TEST(ReadTraFileTest, WrongFormatTestHeader1) {
-   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_header1.tra"), storm::exceptions::WrongFormatException);
+   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_header1.tra"), storm::exceptions::WrongFormatException);
 }
 
 TEST(ReadTraFileTest, WrongFormatTestHeader2) {
-   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_header2.tra"), storm::exceptions::WrongFormatException);
+   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_header2.tra"), storm::exceptions::WrongFormatException);
 }
 
 TEST(ReadTraFileTest, WrongFormatTestTransition) {
-   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_transition.tra"), storm::exceptions::WrongFormatException);
+   ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/wrong_format_transition.tra"), storm::exceptions::WrongFormatException);
 }

From 1f71bb5240bcd252bc6f54bb9bba7777caa94490 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Fri, 20 Dec 2013 16:35:23 +0100
Subject: [PATCH 005/147] Refactored the DeterministicModelParser.

Former-commit-id: 7227d25499a85308abb06f282a8531c0d21d0adb
---
 .gitignore                                    |  3 +
 src/parser/AutoParser.h                       |  4 +-
 src/parser/DeterministicModelParser.cpp       | 28 +++---
 src/parser/DeterministicModelParser.h         | 85 +++++++++++++------
 .../DeterministicSparseTransitionParser.cpp   |  9 +-
 .../DeterministicSparseTransitionParser.h     |  4 -
 src/parser/MarkovAutomatonParser.cpp          |  1 +
 .../MarkovAutomatonSparseTransitionParser.cpp |  9 +-
 src/parser/Parser.cpp                         |  3 +
 src/parser/Parser.h                           |  9 --
 test/functional/parser/CslParserTest.cpp      |  1 +
 test/functional/parser/LtlParserTest.cpp      |  1 +
 test/functional/parser/PrctlParserTest.cpp    |  1 +
 13 files changed, 92 insertions(+), 66 deletions(-)

diff --git a/.gitignore b/.gitignore
index 47ad40437..9abd6bea7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,6 @@ build//CMakeLists.txt
 /*.vcxproj
 /*.filters
 /*.sln
+#Temp texteditor files
+*.orig
+*.*~
diff --git a/src/parser/AutoParser.h b/src/parser/AutoParser.h
index 32baaae40..cec1fad66 100644
--- a/src/parser/AutoParser.h
+++ b/src/parser/AutoParser.h
@@ -48,11 +48,11 @@ class AutoParser {
 			// Do actual parsing
 			switch (type) {
 				case storm::models::DTMC: {
-					this->model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParserAsDtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					this->model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParser::parseDtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
 					break;
 				}
 				case storm::models::CTMC: {
-					this->model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParserAsCtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					this->model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParser::parseCtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
 					break;
 				}
 				case storm::models::MDP: {
diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index 44e484bc0..555b2485e 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -26,8 +26,7 @@ namespace parser {
  * @param stateRewardFile String containing the location of the state reward file (...srew)
  * @param transitionRewardFile String containing the location of the transition reward file (...trew)
  */
-DeterministicModelParserResultContainer<double> parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
-																		std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+DeterministicModelParser::ResultContainer DeterministicModelParser::parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
 	storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionSystemFile)));
 
@@ -36,11 +35,14 @@ DeterministicModelParserResultContainer<double> parseDeterministicModel(std::str
 
 	storm::models::AtomicPropositionsLabeling resultLabeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
 
-	DeterministicModelParserResultContainer<double> result(std::move(resultTransitionSystem), std::move(resultLabeling));
+	DeterministicModelParser::ResultContainer result(std::move(resultTransitionSystem), std::move(resultLabeling));
 
+	// Only parse state rewards of a file is given.
 	if (stateRewardFile != "") {
 		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
 	}
+
+	// Only parse transition rewards of a file is given.
 	if (transitionRewardFile != "") {
 		RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, nullptr);
 		result.transitionRewards.reset(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo)));
@@ -50,24 +52,24 @@ DeterministicModelParserResultContainer<double> parseDeterministicModel(std::str
 }
 
 /*!
- * Uses the Function parseDeterministicModel internally to parse the given input files.
- * @note This is a Short-Hand for Constructing a Dtmc directly from the data returned by @parseDeterministicModel
+ * Uses the parseDeterministicModel function internally to parse the given input files.
+ * @note This is a short-hand for constructing a Dtmc directly from the data returned by @parseDeterministicModel
  * @return A Dtmc Model
  */
-storm::models::Dtmc<double> DeterministicModelParserAsDtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
-														   std::string const & stateRewardFile, std::string const & transitionRewardFile) {
-	DeterministicModelParserResultContainer<double> parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
+storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+
+	DeterministicModelParser::ResultContainer parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
 	return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
 }
 
 /*!
- * Uses the Function parseDeterministicModel internally to parse the given input files.
- * @note This is a Short-Hand for Constructing a Ctmc directly from the data returned by @parseDeterministicModel
+ * Uses the parseDeterministicModel function internally to parse the given input files.
+ * @note This is a short-hand for constructing a Ctmc directly from the data returned by @parseDeterministicModel
  * @return A Ctmc Model
  */
-storm::models::Ctmc<double> DeterministicModelParserAsCtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile, std::string const & transitionRewardFile) {
-	DeterministicModelParserResultContainer<double> parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
+storm::models::Ctmc<double> DeterministicModelParser::parseCtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+
+	DeterministicModelParser::ResultContainer parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
 	return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
 }
 
diff --git a/src/parser/DeterministicModelParser.h b/src/parser/DeterministicModelParser.h
index 273c64c49..c6b64b6c1 100644
--- a/src/parser/DeterministicModelParser.h
+++ b/src/parser/DeterministicModelParser.h
@@ -18,44 +18,77 @@ namespace storm {
 namespace parser {
 
 /*!
- *	@brief Load label and transition file and returns an initialized dtmc or ctmc object.
+ *	@brief Loads a deterministic model (Dtmc or Ctmc) from files.
+ *
+ *	Given the file paths of the files holding the transitions, the atomic propositions and optionally the state- and transition rewards
+ *	it loads the files, parses them and returns the desired model.
  *
  *	@note This class creates a new Dtmc or Ctmc object
  *
  *	@note The labeling representation in the file may use at most as much nodes as are specified in the transition system.
  */
 
+class DeterministicModelParser {
 
-storm::models::Dtmc<double> DeterministicModelParserAsDtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
-storm::models::Ctmc<double> DeterministicModelParserAsCtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
-
-/*!
- * @brief This Class acts as a container much like std::pair for the four return values of the DeterministicModelParser
- */
-template <class T>
-class DeterministicModelParserResultContainer {
 public:
-	storm::storage::SparseMatrix<T> transitionSystem;
-	storm::models::AtomicPropositionsLabeling labeling;
-	boost::optional<std::vector<T>> stateRewards;
-	boost::optional<storm::storage::SparseMatrix<T>> transitionRewards;
-	DeterministicModelParserResultContainer(storm::storage::SparseMatrix<T>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) { }
-	DeterministicModelParserResultContainer(storm::storage::SparseMatrix<T>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) { }
-
-	DeterministicModelParserResultContainer(const DeterministicModelParserResultContainer & other) : transitionSystem(other.transitionSystem), 
-		labeling(other.labeling), stateRewards(other.stateRewards), transitionRewards(other.transitionRewards) {}
-	DeterministicModelParserResultContainer(DeterministicModelParserResultContainer && other) : transitionSystem(std::move(other.transitionSystem)), 
-		labeling(std::move(other.labeling)), stateRewards(std::move(other.stateRewards)), transitionRewards(std::move(other.transitionRewards)) {}
+
+	/*!
+	 * @brief A struct containing the parsed components of a deterministic model.
+	 */
+	struct ResultContainer {
+
+		ResultContainer(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
+			// Intentionally left empty.
+		}
+
+		ResultContainer(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
+			// Intentionally left empty.
+		}
+
+		// A matrix representing the transitions of the model
+		storm::storage::SparseMatrix<double> transitionSystem;
+
+		// The labels of each state.
+		storm::models::AtomicPropositionsLabeling labeling;
+
+		// Optional rewards for each state.
+		boost::optional<std::vector<double>> stateRewards;
+
+		// Optional rewards for each transition.
+		boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
+	};
+
+
+	/*!
+	 * @brief Parse a Dtmc.
+	 */
+	static storm::models::Dtmc<double> parseDtmc(std::string const & transitionSystemFile,
+												 std::string const & labelingFile,
+												 std::string const & stateRewardFile = "",
+												 std::string const & transitionRewardFile = "");
+
+	/*!
+	 * @brief Parse a Ctmc.
+	 */
+	static storm::models::Ctmc<double> parseCtmc(std::string const & transitionSystemFile,
+										  	     std::string const & labelingFile,
+										  	     std::string const & stateRewardFile = "",
+										  	     std::string const & transitionRewardFile = "");
+
 private:
-	DeterministicModelParserResultContainer() {}
-};
 
+	/*!
+	 * @brief Call sub-parsers on the given files and fill the container with the results.
+	 */
+	static ResultContainer parseDeterministicModel(std::string const & transitionSystemFile,
+												   std::string const & labelingFile,
+												   std::string const & stateRewardFile = "",
+												   std::string const & transitionRewardFile = "");
 
-DeterministicModelParserResultContainer<double> parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+};
 
 } /* namespace parser */
+
 } /* namespace storm */
+
 #endif /* STORM_PARSER_DETERMINISTICMODELPARSER_H_ */
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 76cd49af5..683042353 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -7,22 +7,15 @@
 
 #include "src/parser/DeterministicSparseTransitionParser.h"
 
-#include <errno.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <locale.h>
-
-#include <cstdlib>
 #include <cstdio>
 #include <cstring>
+#include <cstdint>
 #include <clocale>
 #include <iostream>
 #include <string>
 
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
-#include <cstdint>
 #include "src/settings/Settings.h"
 
 #include "log4cplus/logger.h"
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index 7fcd62a1f..c44583b97 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -2,11 +2,7 @@
 #define STORM_PARSER_TRAPARSER_H_
 
 #include "src/storage/SparseMatrix.h"
-
 #include "src/parser/Parser.h"
-#include "src/utility/OsDetection.h"
-
-#include <memory>
 
 namespace storm {
 
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index 8b74a896b..b8df6390a 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -1,6 +1,7 @@
 #include "MarkovAutomatonParser.h"
 #include "AtomicPropositionLabelingParser.h"
 #include "SparseStateRewardParser.h"
+#include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
 
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index ce89951d9..7d3336ae8 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -1,6 +1,7 @@
 #include "MarkovAutomatonSparseTransitionParser.h"
 
 #include "src/settings/Settings.h"
+#include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
 
@@ -18,8 +19,8 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 	}
 
 	// Now read the transitions.
-	int_fast64_t source, target = -1;
-	int_fast64_t lastsource = -1;
+	uint_fast64_t source, target = 0;
+	uint_fast64_t lastsource = 0;
 	bool encounteredEOF = false;
 	bool stateHasMarkovianChoice = false;
 	bool stateHasProbabilisticChoice = false;
@@ -150,8 +151,8 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 	buf = storm::parser::forwardToNextLine(buf, lineEndings);
 
 	// Now read the transitions.
-	int_fast64_t source, target = -1;
-	int_fast64_t lastsource = -1;
+	uint_fast64_t source, target = 0;
+	uint_fast64_t lastsource = 0;
 	bool encounteredEOF = false;
 	uint_fast64_t currentChoice = 0;
 	while (buf[0] != '\0' && !encounteredEOF) {
diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp
index 67b2772d7..6fb26ef4b 100644
--- a/src/parser/Parser.cpp
+++ b/src/parser/Parser.cpp
@@ -1,10 +1,13 @@
 #include "src/parser/Parser.h"
 
+#include <fcntl.h>
 #include <iostream>
+#include <fstream>
 #include <cstring>
 #include <string>
 #include <cerrno>
 
+#include <boost/integer/integer_mask.hpp>
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
 #include "src/utility/OsDetection.h"
diff --git a/src/parser/Parser.h b/src/parser/Parser.h
index 3fee43b98..e7fcf4dab 100644
--- a/src/parser/Parser.h
+++ b/src/parser/Parser.h
@@ -11,18 +11,9 @@
 #include "src/utility/OsDetection.h"
 
 #include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <iostream>
-#include <fstream>
-#include <memory>
 #include <vector>
 #include <string>
 
-#include <boost/integer/integer_mask.hpp>
-#include "src/exceptions/FileIoException.h"
-#include "src/exceptions/WrongFormatException.h"
-
 namespace storm {
 
 /*!
diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp
index fb758e951..4e4a67af9 100644
--- a/test/functional/parser/CslParserTest.cpp
+++ b/test/functional/parser/CslParserTest.cpp
@@ -8,6 +8,7 @@
 #include "gtest/gtest.h"
 #include "storm-config.h"
 #include "src/parser/CslParser.h"
+#include "src/exceptions/WrongFormatException.h"
 
 TEST(CslParserTest, parseApOnlyTest) {
 	std::string formula = "ap";
diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp
index 00df82ff9..1da53769d 100644
--- a/test/functional/parser/LtlParserTest.cpp
+++ b/test/functional/parser/LtlParserTest.cpp
@@ -8,6 +8,7 @@
 #include "gtest/gtest.h"
 #include "storm-config.h"
 #include "src/parser/LtlParser.h"
+#include "src/exceptions/WrongFormatException.h"
 
 TEST(LtlParserTest, parseApOnlyTest) {
 	std::string formula = "ap";
diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp
index 923b5f941..c51cf3164 100644
--- a/test/functional/parser/PrctlParserTest.cpp
+++ b/test/functional/parser/PrctlParserTest.cpp
@@ -9,6 +9,7 @@
 #include "gtest/gtest.h"
 #include "storm-config.h"
 #include "src/parser/PrctlParser.h"
+#include "src/exceptions/WrongFormatException.h"
 
 TEST(PrctlParserTest, parseApOnlyTest) {
 	std::string ap = "ap";

From 4245b3c4e3f538e848d66a5c8dc8835c27fb3aff Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 1 Jan 2014 19:15:37 +0100
Subject: [PATCH 006/147] Changed parsers to be compilable again.

- Mostly effects of the SparseMatrix redesign.
- Plus some missing includes.


Former-commit-id: 11c5bc99704520a6fe93eb859ae3aaf56314c93b
---
 src/parser/DeterministicModelParser.cpp       |   4 +-
 .../DeterministicSparseTransitionParser.cpp   |  44 +++-----
 src/parser/LtlFileParser.cpp                  |   4 +
 src/parser/MarkovAutomatonParser.cpp          |  13 ++-
 .../MarkovAutomatonSparseTransitionParser.cpp |   7 +-
 .../MarkovAutomatonSparseTransitionParser.h   |   5 +-
 src/parser/PrctlFileParser.cpp                |   1 +
 .../parser/MarkovAutomatonParserTest.cpp      | 106 ++++++++++++------
 8 files changed, 109 insertions(+), 75 deletions(-)

diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index 555b2485e..c7411b14f 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -59,7 +59,7 @@ DeterministicModelParser::ResultContainer DeterministicModelParser::parseDetermi
 storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
 	DeterministicModelParser::ResultContainer parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
-	return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
+	return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 }
 
 /*!
@@ -70,7 +70,7 @@ storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string cons
 storm::models::Ctmc<double> DeterministicModelParser::parseCtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
 	DeterministicModelParser::ResultContainer parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
-	return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
+	return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 }
 
 } /* namespace parser */
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 683042353..4410254d7 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -14,6 +14,8 @@
 #include <iostream>
 #include <string>
 
+#include "src/utility/constants.h"
+
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
 #include "src/settings/Settings.h"
@@ -150,15 +152,11 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 		buf = storm::parser::forwardToNextLine(buf, lineEndings);
 	}
 
-	// Creating matrix here.
+	// Creating matrix builder here.
 	// The number of non-zero elements is computed by firstPass().
-	LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
-	storm::storage::SparseMatrix<double> resultMatrix(firstPass.highestStateIndex + 1);
-	resultMatrix.initialize(firstPass.numberOfNonzeroEntries);
-	if (!resultMatrix.isInitialized()) {
-		LOG4CPLUS_ERROR(logger, "Could not create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
-		throw std::bad_alloc();
-	}
+	// The contents are inserted during the readout of the file, below.
+	// The actual matrix will be build once all contents are inserted.
+	storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
 
 	uint_fast64_t row, col, lastRow = 0;
 	double val;
@@ -189,7 +187,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 		if (lastRow != row) {
 			if (!rowHadDiagonalEntry) {
 				if (insertDiagonalEntriesIfMissing) {
-					resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constGetZero<double>());
+					resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
 					LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
 				} else {
 					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
@@ -200,7 +198,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 			for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
 				hadDeadlocks = true;
 				if (fixDeadlocks) {
-					resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constGetOne<double>());
+					resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
 					rowHadDiagonalEntry = true;
 					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
 				} else {
@@ -218,7 +216,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 
 		if (col > row && !rowHadDiagonalEntry) {
 			if (insertDiagonalEntriesIfMissing) {
-				resultMatrix.addNextValue(row, row, storm::utility::constGetZero<double>());
+				resultMatrix.addNextValue(row, row, storm::utility::constantZero<double>());
 				LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
 			} else {
 				LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
@@ -232,7 +230,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 
 	if (!rowHadDiagonalEntry) {
 		if (insertDiagonalEntriesIfMissing) {
-			resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constGetZero<double>());
+			resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
 			LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
 		} else {
 			LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
@@ -242,10 +240,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 	// If we encountered deadlock and did not fix them, now is the time to throw the exception.
 	if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
 
-	// Finalize Matrix.
-	resultMatrix.finalize();
-
-	return resultMatrix;
+	return resultMatrix.build();
 }
 
 /*!
@@ -302,15 +297,11 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 	}
 
 
-	// Creating matrix here.
+	// Creating matrix builder here.
 	// The number of non-zero elements is computed by firstPass().
-	LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
-	storm::storage::SparseMatrix<double> resultMatrix(firstPass.highestStateIndex + 1);
-	resultMatrix.initialize(firstPass.numberOfNonzeroEntries);
-	if (!resultMatrix.isInitialized()) {
-		LOG4CPLUS_ERROR(logger, "Could not create matrix of size " << (firstPass.highestStateIndex+1) << " x " << (firstPass.highestStateIndex+1) << ".");
-		throw std::bad_alloc();
-	}
+	// The contents are inserted during the readout of the file, below.
+	// The actual matrix will be build once all contents are inserted.
+	storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
 
 	uint_fast64_t row, col;
 	double val;
@@ -329,10 +320,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseD
 		buf = trimWhitespaces(buf);
 	}
 
-	// Finalize Matrix.
-	resultMatrix.finalize();
-
-	return resultMatrix;
+	return resultMatrix.build();
 }
 
 }  // namespace parser
diff --git a/src/parser/LtlFileParser.cpp b/src/parser/LtlFileParser.cpp
index 7f77ff4da..a53557b89 100644
--- a/src/parser/LtlFileParser.cpp
+++ b/src/parser/LtlFileParser.cpp
@@ -5,9 +5,13 @@
  *      Author: thomas
  */
 
+#include <fstream>
+
 #include "LtlFileParser.h"
 #include "LtlParser.h"
 
+#include "src/exceptions/FileIoException.h"
+
 namespace storm {
 namespace parser {
 
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index b8df6390a..4003b6a5a 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -8,12 +8,19 @@ namespace storm {
 namespace parser {
 
 storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename) {
+
+	// Parse the transitions of the Markov Automaton.
 	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType transitionResult(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(transitionsFilename));
-	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionResult.transitionMatrix.getColumnCount(), labelingFilename));
+
+	// Build the actual transition matrix using the MatrixBuilder provided by the transitionResult.
+	storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0));
+
+	// Parse the state labeling.
+	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionMatrix.getColumnCount(), labelingFilename));
 
 	boost::optional<std::vector<double>> stateRewards;
 	if (stateRewardFilename != "") {
-		stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(transitionResult.transitionMatrix.getColumnCount(), stateRewardFilename));
+		stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(transitionMatrix.getColumnCount(), stateRewardFilename));
 	}
 
 	if (transitionRewardFilename != "") {
@@ -21,7 +28,7 @@ storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomat
 		throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
 	}
 
-	storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionResult.transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>());
+	storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 
 	return resultingAutomaton;
 }
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 7d3336ae8..1ca4f7264 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -164,7 +164,7 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 			if (fixDeadlocks) {
 				for (uint_fast64_t index = lastsource + 1; index < source; ++index) {
 					result.nondeterministicChoiceIndices[index] = currentChoice;
-					result.transitionMatrix.addNextValue(currentChoice, index, 1);
+					result.transitionMatrixBuilder.addNextValue(currentChoice, index, 1);
 					++currentChoice;
 				}
 			} else {
@@ -220,7 +220,7 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 				double val = checked_strtod(buf, &buf);
 
 				// Record the value as well as the exit rate in case of a Markovian choice.
-				result.transitionMatrix.addNextValue(currentChoice, target, val);
+				result.transitionMatrixBuilder.addNextValue(currentChoice, target, val);
 				if (isMarkovianChoice) {
 					result.exitRates[source] += val;
 				}
@@ -236,9 +236,6 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 		++currentChoice;
 	}
 
-	// As we have added all entries at this point, we need to finalize the matrix.
-	result.transitionMatrix.finalize();
-
 	// Put a sentinel element at the end.
 	result.nondeterministicChoiceIndices[firstPassResult.highestStateIndex + 1] = currentChoice;
 
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index e576730d2..54c6aae6a 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -44,13 +44,12 @@ public:
 		 * Creates a new instance of the struct using the result of the first pass to correctly initialize the container.
 		 * @param firstPassResult A reference to the result of the first pass.
 		 */
-		ResultType(FirstPassResult const& firstPassResult) : transitionMatrix(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
-			transitionMatrix.initialize(firstPassResult.numberOfNonzeroEntries);
+		ResultType(FirstPassResult const& firstPassResult) : transitionMatrixBuilder(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1, firstPassResult.numberOfNonzeroEntries), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
 			// Intentionally left empty.
 		}
 
 		// A matrix representing the transitions of the model.
-		storm::storage::SparseMatrix<double> transitionMatrix;
+		storm::storage::SparseMatrixBuilder<double> transitionMatrixBuilder;
 
 		// A vector indicating which rows of the matrix represent the choices of a given state.
 		std::vector<uint_fast64_t> nondeterministicChoiceIndices;
diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp
index ccf4c62b1..b4f2b3f2e 100644
--- a/src/parser/PrctlFileParser.cpp
+++ b/src/parser/PrctlFileParser.cpp
@@ -9,6 +9,7 @@
 
 #include "PrctlFileParser.h"
 #include "PrctlParser.h"
+#include "src/exceptions/FileIoException.h"
 
 namespace storm {
 namespace parser {
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index a5803d119..d4ad69b75 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -25,14 +25,18 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
 	// The file that will be used for the test.
 	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra";
 
+	// Execute the parser.
 	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
 
+	// Build the actual transition matrix.
+	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
+
 	// Test all sizes and counts.
-	ASSERT_EQ(result.transitionMatrix.getColumnCount(), STATE_COUNT);
-	ASSERT_EQ(result.transitionMatrix.getRowCount(), CHOICE_COUNT);
-	ASSERT_EQ(result.transitionMatrix.getNonZeroEntryCount(), 12);
-	ASSERT_EQ(result.markovianChoices.getSize(), CHOICE_COUNT);
-	ASSERT_EQ(result.markovianStates.getSize(), STATE_COUNT);
+	ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
+	ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
+	ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
+	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
+	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
 	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
 	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
 	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
@@ -65,32 +69,51 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
 	ASSERT_EQ(result.exitRates[5], 0);
 
 	// Finally, test the transition matrix itself.
-	ASSERT_EQ(result.transitionMatrix.getValue(0,1), 2);
-	ASSERT_EQ(result.transitionMatrix.getValue(1,2), 1);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,0), 1);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,1), 2);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,3), 4);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,4), 8);
-	ASSERT_EQ(result.transitionMatrix.getValue(3,2), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(3,3), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(4,3), 1);
-	ASSERT_EQ(result.transitionMatrix.getValue(5,1), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(5,5), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(6,5), 1);
+	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
+
+	ASSERT_EQ(cIter->second, 2);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->second, 2);
+	cIter++;
+	ASSERT_EQ(cIter->second, 4);
+	cIter++;
+	ASSERT_EQ(cIter->second, 8);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
 
 TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
 	// The file that will be used for the test.
 	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespace_input_01.tra";
 
+	// Execute the parser.
 	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
 
+	// Build the actual transition matrix.
+	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
+
 	// Test all sizes and counts.
-	ASSERT_EQ(result.transitionMatrix.getColumnCount(), STATE_COUNT);
-	ASSERT_EQ(result.transitionMatrix.getRowCount(), CHOICE_COUNT);
-	ASSERT_EQ(result.transitionMatrix.getNonZeroEntryCount(), 12);
-	ASSERT_EQ(result.markovianChoices.getSize(), CHOICE_COUNT);
-	ASSERT_EQ(result.markovianStates.getSize(), STATE_COUNT);
+	ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
+	ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
+	ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
+	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
+	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
 	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
 	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
 	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
@@ -123,18 +146,33 @@ TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
 	ASSERT_EQ(result.exitRates[5], 0);
 
 	// Finally, test the transition matrix itself.
-	ASSERT_EQ(result.transitionMatrix.getValue(0,1), 2);
-	ASSERT_EQ(result.transitionMatrix.getValue(1,2), 1);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,0), 1);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,1), 2);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,3), 4);
-	ASSERT_EQ(result.transitionMatrix.getValue(2,4), 8);
-	ASSERT_EQ(result.transitionMatrix.getValue(3,2), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(3,3), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(4,3), 1);
-	ASSERT_EQ(result.transitionMatrix.getValue(5,1), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(5,5), 0.5);
-	ASSERT_EQ(result.transitionMatrix.getValue(6,5), 1);
+	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
+
+	ASSERT_EQ(cIter->second, 2);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->second, 2);
+	cIter++;
+	ASSERT_EQ(cIter->second, 4);
+	cIter++;
+	ASSERT_EQ(cIter->second, 8);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
 
 //TODO: Deadlock Test. I am quite sure that the deadlock state handling does not behave quite right.

From 8adee3629bd76eaa13552238d624fa4c417ef059 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Thu, 2 Jan 2014 01:30:00 +0100
Subject: [PATCH 007/147] Removed duplicated code in
 DeterministicSparseTransitionParser while still keeping it readable and the
 interface intact.

Next up: Refactor the Nondeterministic*Parser.


Former-commit-id: 108eea60a0418ec4bfa515619456549fae6a5c79
---
 .../DeterministicSparseTransitionParser.cpp   | 325 +++++++-----------
 .../DeterministicSparseTransitionParser.h     |  36 +-
 src/parser/MarkovAutomatonParser.cpp          |   3 +
 src/parser/MarkovAutomatonParser.h            |   2 +-
 .../MarkovAutomatonSparseTransitionParser.h   |   2 +-
 5 files changed, 166 insertions(+), 202 deletions(-)

diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 4410254d7..03b94c78c 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -28,19 +28,18 @@ namespace storm {
 
 namespace parser {
 
-/*!
- *	@brief	Perform first pass through the file and obtain number of
- *	non-zero cells and maximum node id.
- *
- *	This method does the first pass through the .tra file and computes
- *	the number of non-zero elements.
- *	It also calculates the maximum node id and stores it in maxnode.
- *
- *	@return The number of non-zero elements
- *	@param buf Data to scan. Is expected to be some char array.
- *	@param maxnode Is set to highest id of all nodes.
- */
+storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing) {
+
+	return DeterministicSparseTransitionParser::parse(filename, false, insertDiagonalEntriesIfMissing);
+}
+
+storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+
+	return DeterministicSparseTransitionParser::parse(filename, true, false, rewardMatrixInformation);
+}
+
 DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing) {
+
 	DeterministicSparseTransitionParser::FirstPassResult result;
 
 	// Skip the format hint if it is there.
@@ -107,220 +106,156 @@ DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransiti
 	return result;
 }
 
-/*!
- *	Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
- *
- *	Matrices created with this method have to be freed with the delete operator.
- *	@param filename input .tra file's name.
- *	@return a pointer to the created sparse matrix.
- */
-
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing) {
-
+storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(std::string const& filename, bool rewardFile, bool insertDiagonalEntriesIfMissing, RewardMatrixInformationStruct const& rewardMatrixInformation) {
 	// Enforce locale where decimal point is '.'.
-	setlocale(LC_NUMERIC, "C");
-
-	if (!fileExistsAndIsReadable(filename.c_str())) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-		throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
-	}
+		setlocale(LC_NUMERIC, "C");
 
-	// Find out about the used line endings.
-	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
-
-	// Open file.
-	MappedFile file(filename.c_str());
-	char* buf = file.data;
-
-	// Perform first pass, i.e. count entries that are not zero.
-
-	DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, insertDiagonalEntriesIfMissing);
-
-	LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
-
-	// If first pass returned zero, the file format was wrong.
-	if (firstPass.numberOfNonzeroEntries == 0) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
-		throw storm::exceptions::WrongFormatException();
-	}
-
-	// Perform second pass.
-
-	// Skip the format hint if it is there.
-	buf = trimWhitespaces(buf);
-	if(buf[0] != '0') {
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
-	}
+		if (!fileExistsAndIsReadable(filename.c_str())) {
+			LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+			throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
+		}
 
-	// Creating matrix builder here.
-	// The number of non-zero elements is computed by firstPass().
-	// The contents are inserted during the readout of the file, below.
-	// The actual matrix will be build once all contents are inserted.
-	storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
+		// Find out about the used line endings.
+		SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
 
-	uint_fast64_t row, col, lastRow = 0;
-	double val;
-	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-	bool hadDeadlocks = false;
-	bool rowHadDiagonalEntry = false;
+		// Open file.
+		MappedFile file(filename.c_str());
+		char* buf = file.data;
 
+		// Perform first pass, i.e. count entries that are not zero.
 
-	// Read all transitions from file. Note that we assume that the
-	// transitions are listed in canonical order, otherwise this will not
-	// work, i.e. the values in the matrix will be at wrong places.
-	while (buf[0] != '\0') {
+		DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, insertDiagonalEntriesIfMissing);
 
-		// Read next transition.
-		row = checked_strtol(buf, &buf);
-		col = checked_strtol(buf, &buf);
-		val = checked_strtod(buf, &buf);
+		LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
 
-		// Read probability of this transition.
-		// Check, if the value is a probability, i.e. if it is between 0 and 1.
-		if ((val < 0.0) || (val > 1.0)) {
-			LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
+		// If first pass returned zero, the file format was wrong.
+		if (firstPass.numberOfNonzeroEntries == 0) {
+			LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
 			throw storm::exceptions::WrongFormatException();
 		}
 
-		// Test if we moved to a new row.
-		// Handle all incomplete or skipped rows.
-		if (lastRow != row) {
-			if (!rowHadDiagonalEntry) {
-				if (insertDiagonalEntriesIfMissing) {
-					resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
-					LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
-				} else {
-					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
-				}
-				// No increment for lastRow.
-				rowHadDiagonalEntry = true;
-			}
-			for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
-				hadDeadlocks = true;
-				if (fixDeadlocks) {
-					resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
-					rowHadDiagonalEntry = true;
-					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
-				} else {
-					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
-					// Before throwing the appropriate exception we will give notice of all deadlock states.
-				}
-			}
-			lastRow = row;
-			rowHadDiagonalEntry = false;
-		}
+		// Perform second pass.
 
-		if (col == row) {
-			rowHadDiagonalEntry = true;
+		// Skip the format hint if it is there.
+		buf = trimWhitespaces(buf);
+		if(buf[0] != '0') {
+			buf = storm::parser::forwardToNextLine(buf, lineEndings);
 		}
 
-		if (col > row && !rowHadDiagonalEntry) {
-			if (insertDiagonalEntriesIfMissing) {
-				resultMatrix.addNextValue(row, row, storm::utility::constantZero<double>());
-				LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
+		if(rewardFile) {
+			// The reward matrix should match the size of the transition matrix.
+			if (firstPass.highestStateIndex + 1 > rewardMatrixInformation.rowCount || firstPass.highestStateIndex + 1 > rewardMatrixInformation.columnCount) {
+				LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
+				throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
 			} else {
-				LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
+				// If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
+				firstPass.highestStateIndex = rewardMatrixInformation.rowCount - 1;
 			}
-			rowHadDiagonalEntry = true;
 		}
 
-		resultMatrix.addNextValue(row, col, val);
-		buf = trimWhitespaces(buf);
-	}
-
-	if (!rowHadDiagonalEntry) {
-		if (insertDiagonalEntriesIfMissing) {
-			resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
-			LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
-		} else {
-			LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
-		}
-	}
-
-	// If we encountered deadlock and did not fix them, now is the time to throw the exception.
-	if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
-
-	return resultMatrix.build();
-}
-
-/*!
- *	Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
- *
- *	Matrices created with this method have to be freed with the delete operator.
- *	@param filename input .tra file's name.
- *	@return a pointer to the created sparse matrix.
- */
-
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
-	// Enforce locale where decimal point is '.'.
-	setlocale(LC_NUMERIC, "C");
-
-	if (!fileExistsAndIsReadable(filename.c_str())) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-		throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
-	}
+		// Creating matrix builder here.
+		// The actual matrix will be build once all contents are inserted.
+		storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
 
-	// Find out about the used line endings.
-	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+		uint_fast64_t row, col, lastRow = 0;
+		double val;
+		bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+		bool hadDeadlocks = false;
+		bool rowHadDiagonalEntry = false;
 
-	// Open file.
-	MappedFile file(filename.c_str());
-	char* buf = file.data;
 
-	// Perform first pass, i.e. count entries that are not zero.
+		// Read all transitions from file. Note that we assume that the
+		// transitions are listed in canonical order, otherwise this will not
+		// work, i.e. the values in the matrix will be at wrong places.
 
-	DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, false);
+		// Different parsing routines for transition systems and transition rewards.
+		if(rewardFile) {
+			while (buf[0] != '\0') {
 
-	LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
-
-	// If first pass returned zero, the file format was wrong.
-	if (firstPass.numberOfNonzeroEntries == 0) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
-		throw storm::exceptions::WrongFormatException();
-	}
-
-	// Perform second pass.
-
-	// Skip the format hint if it is there.
-	buf = trimWhitespaces(buf);
-	if(buf[0] != '0') {
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
-	}
+				// Read next transition.
+				row = checked_strtol(buf, &buf);
+				col = checked_strtol(buf, &buf);
+				val = checked_strtod(buf, &buf);
 
-	// The reward matrix should match the size of the transition matrix.
-	if (firstPass.highestStateIndex + 1 > rewardMatrixInformation.rowCount || firstPass.highestStateIndex + 1 > rewardMatrixInformation.columnCount) {
-		LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
-		throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
-	} else {
-		// If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
-		firstPass.highestStateIndex = rewardMatrixInformation.rowCount - 1;
-	}
+				resultMatrix.addNextValue(row, col, val);
+				buf = trimWhitespaces(buf);
+			}
+		} else {
+			while (buf[0] != '\0') {
+
+				// Read next transition.
+				row = checked_strtol(buf, &buf);
+				col = checked_strtol(buf, &buf);
+				val = checked_strtod(buf, &buf);
+
+				// Read probability of this transition.
+				// Check, if the value is a probability, i.e. if it is between 0 and 1.
+				if ((val < 0.0) || (val > 1.0)) {
+					LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
+					throw storm::exceptions::WrongFormatException();
+				}
 
+				// Test if we moved to a new row.
+				// Handle all incomplete or skipped rows.
+				if (lastRow != row) {
+					if (!rowHadDiagonalEntry) {
+						if (insertDiagonalEntriesIfMissing) {
+							resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
+							LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
+						} else {
+							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+						}
+						// No increment for lastRow.
+						rowHadDiagonalEntry = true;
+					}
+					for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
+						hadDeadlocks = true;
+						if (fixDeadlocks) {
+							resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
+							rowHadDiagonalEntry = true;
+							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
+						} else {
+							LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
+							// Before throwing the appropriate exception we will give notice of all deadlock states.
+						}
+					}
+					lastRow = row;
+					rowHadDiagonalEntry = false;
+				}
 
-	// Creating matrix builder here.
-	// The number of non-zero elements is computed by firstPass().
-	// The contents are inserted during the readout of the file, below.
-	// The actual matrix will be build once all contents are inserted.
-	storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
+				if (col == row) {
+					rowHadDiagonalEntry = true;
+				}
 
-	uint_fast64_t row, col;
-	double val;
+				if (col > row && !rowHadDiagonalEntry) {
+					if (insertDiagonalEntriesIfMissing) {
+						resultMatrix.addNextValue(row, row, storm::utility::constantZero<double>());
+						LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
+					} else {
+						LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
+					}
+					rowHadDiagonalEntry = true;
+				}
 
-	// Read all transitions from file. Note that we assume that the
-	// transitions are listed in canonical order, otherwise this will not
-	// work, i.e. the values in the matrix will be at wrong places.
-	while (buf[0] != '\0') {
+				resultMatrix.addNextValue(row, col, val);
+				buf = trimWhitespaces(buf);
+			}
 
-		// Read next transition.
-		row = checked_strtol(buf, &buf);
-		col = checked_strtol(buf, &buf);
-		val = checked_strtod(buf, &buf);
+			if (!rowHadDiagonalEntry) {
+				if (insertDiagonalEntriesIfMissing) {
+					resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
+					LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
+				} else {
+					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+				}
+			}
 
-		resultMatrix.addNextValue(row, col, val);
-		buf = trimWhitespaces(buf);
-	}
+			// If we encountered deadlock and did not fix them, now is the time to throw the exception.
+			if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
+		}
 
-	return resultMatrix.build();
+		// Finally, build the actual matrix and return it.
+		return resultMatrix.build();
 }
 
 }  // namespace parser
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index c44583b97..45ce9ac26 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -27,21 +27,35 @@ public:
 	};
 
 	/*!
-	 *	@brief	Load a deterministic transition system from file and create a
-	 *	sparse adjacency matrix whose entries represent the weights of the edges
+	 * Load a deterministic transition system from file and create a
+	 * sparse adjacency matrix whose entries represent the weights of the edges.
+	 *
+	 * @param filename The path of file to be parsed.
+	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+	 * @return A SparseMatrix containing the parsed transition system.
 	 */
 	static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing = true);
 
 	/*!
-	 *	@brief	Load the transition rewards for a deterministic transition system from file and create a
-	 *	sparse adjacency matrix whose entries represent the rewards of the respective transitions.
+	 * Load the transition rewards for a deterministic transition system from file and create a
+	 * sparse adjacency matrix whose entries represent the rewards of the respective transitions.
+	 */
+
+	/*!
+	 * Load the transition rewards for a deterministic transition system from file and create a
+	 * sparse adjacency matrix whose entries represent the rewards of the respective transitions.
+	 *
+	 * @param filename The path of file to be parsed.
+	 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
+	 * @return A SparseMatrix containing the parsed transition rewards.
 	 */
 	static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation);
 
 private:
 
 	/*
-	 * Performs the first pass on the input pointed to by the given buffer.
+	 * Performs the first pass on the input pointed to by the given buffer to obtain the number of
+	 * transitions and the maximum node id.
 	 *
 	 * @param buffer The buffer that cointains the input.
 	 * @param lineEndings The line endings that are to be used while parsing.
@@ -50,6 +64,18 @@ private:
 	 */
 	static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing = true);
 
+	/*
+	 * The main parsing routine.
+	 * Opens the given file, calls the first pass and performs the second pass, parsing the content of the file into a SparseMatrix.
+	 *
+	 * @param filename The path of file to be parsed.
+	 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
+	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+	 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
+	 * @return A SparseMatrix containing the parsed file contents.
+	 */
+	static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool rewardFile, bool insertDiagonalEntriesIfMissing = false, RewardMatrixInformationStruct const& rewardMatrixInformation = nullptr);
+
 };
 
 } // namespace parser
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index 4003b6a5a..cf98ded11 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -18,16 +18,19 @@ storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomat
 	// Parse the state labeling.
 	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionMatrix.getColumnCount(), labelingFilename));
 
+	// If given, parse the state rewards file.
 	boost::optional<std::vector<double>> stateRewards;
 	if (stateRewardFilename != "") {
 		stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(transitionMatrix.getColumnCount(), stateRewardFilename));
 	}
 
+	// Since Markov Automata do not support transition rewards no path should be given here.
 	if (transitionRewardFilename != "") {
 		LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata.");
 		throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
 	}
 
+	// Put the pieces together to generate the Markov Automaton.
 	storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 
 	return resultingAutomaton;
diff --git a/src/parser/MarkovAutomatonParser.h b/src/parser/MarkovAutomatonParser.h
index 53354ba55..ae8005006 100644
--- a/src/parser/MarkovAutomatonParser.h
+++ b/src/parser/MarkovAutomatonParser.h
@@ -20,7 +20,7 @@ public:
 	 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
 	 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
 	 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
-	 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
+	 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton. This should be empty as transition rewards are not supported by Markov Automata.
 	 */
 	static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename);
 };
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index 54c6aae6a..ef89371e0 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -30,7 +30,7 @@ public:
 		// The highest state index that appears in the model.
 		uint_fast64_t highestStateIndex;
 
-		// The total number of choices in the model.
+		// The total number of nondeterministic choices in the model.
 		uint_fast64_t numberOfChoices;
 	};
 

From cc71a002f4bd9bc81d7401812d5f3f50e2f6a118 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Thu, 2 Jan 2014 16:46:53 +0100
Subject: [PATCH 008/147] Refactored
 NondeterministicSparseTransitionParser.h/.cpp.

-Changed structure to conform to common parser structure: static class with two passes and structs to handle value passing.
-Killed all warnings (signed unsigned interger compare)
-Made parser more flexible: Is now able to ignore arbitrarily many columns after the value column (instead of only one).
-Threw out a number of unnecessary includes.
-more...

Next up: Refactor NondeterministicModelParser.h/.cpp


Former-commit-id: fd2fdb7fdf88af38f733ed6f83ef2d353a614e2f
---
 .../DeterministicSparseTransitionParser.cpp   |  18 +-
 .../DeterministicSparseTransitionParser.h     |   4 +-
 .../MarkovAutomatonSparseTransitionParser.cpp |   2 +-
 src/parser/NondeterministicModelParser.cpp    |  18 +-
 ...NondeterministicSparseTransitionParser.cpp | 565 +++++++-----------
 .../NondeterministicSparseTransitionParser.h  | 113 +++-
 src/parser/Parser.cpp                         |  23 +
 src/parser/Parser.h                           |   5 +
 8 files changed, 373 insertions(+), 375 deletions(-)

diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 03b94c78c..2ac9098bd 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -30,12 +30,14 @@ namespace parser {
 
 storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing) {
 
-	return DeterministicSparseTransitionParser::parse(filename, false, insertDiagonalEntriesIfMissing);
+	RewardMatrixInformationStruct nullInformation;
+
+	return DeterministicSparseTransitionParser::parse(filename, false, nullInformation, insertDiagonalEntriesIfMissing);
 }
 
 storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
 
-	return DeterministicSparseTransitionParser::parse(filename, true, false, rewardMatrixInformation);
+	return DeterministicSparseTransitionParser::parse(filename, true, rewardMatrixInformation);
 }
 
 DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing) {
@@ -44,7 +46,7 @@ DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransiti
 
 	// Skip the format hint if it is there.
 	buf = trimWhitespaces(buf);
-	if(buf[0] != '0') {
+	if(buf[0] < '0' || buf[0] > '9') {
 		buf = storm::parser::forwardToNextLine(buf, lineEndings);
 	}
 
@@ -53,7 +55,7 @@ DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransiti
 	bool rowHadDiagonalEntry = false;
 	while (buf[0] != '\0') {
 
-		// Read the transition..
+		// Read the transition.
 		row = checked_strtol(buf, &buf);
 		col = checked_strtol(buf, &buf);
 		// The actual read value is not needed here.
@@ -106,7 +108,7 @@ DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransiti
 	return result;
 }
 
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(std::string const& filename, bool rewardFile, bool insertDiagonalEntriesIfMissing, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(std::string const& filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation, bool insertDiagonalEntriesIfMissing) {
 	// Enforce locale where decimal point is '.'.
 		setlocale(LC_NUMERIC, "C");
 
@@ -138,11 +140,11 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(
 
 		// Skip the format hint if it is there.
 		buf = trimWhitespaces(buf);
-		if(buf[0] != '0') {
+		if(buf[0] < '0' || buf[0] > '9') {
 			buf = storm::parser::forwardToNextLine(buf, lineEndings);
 		}
 
-		if(rewardFile) {
+		if(isRewardFile) {
 			// The reward matrix should match the size of the transition matrix.
 			if (firstPass.highestStateIndex + 1 > rewardMatrixInformation.rowCount || firstPass.highestStateIndex + 1 > rewardMatrixInformation.columnCount) {
 				LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
@@ -169,7 +171,7 @@ storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(
 		// work, i.e. the values in the matrix will be at wrong places.
 
 		// Different parsing routines for transition systems and transition rewards.
-		if(rewardFile) {
+		if(isRewardFile) {
 			while (buf[0] != '\0') {
 
 				// Read next transition.
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index 45ce9ac26..b9bb1621e 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -59,7 +59,7 @@ private:
 	 *
 	 * @param buffer The buffer that cointains the input.
 	 * @param lineEndings The line endings that are to be used while parsing.
-	 * @param insertDiagonalEntriesIfMissing Flag determining whether
+	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 	 * @return A structure representing the result of the first pass.
 	 */
 	static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing = true);
@@ -74,7 +74,7 @@ private:
 	 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
 	 * @return A SparseMatrix containing the parsed file contents.
 	 */
-	static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool rewardFile, bool insertDiagonalEntriesIfMissing = false, RewardMatrixInformationStruct const& rewardMatrixInformation = nullptr);
+	static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation, bool insertDiagonalEntriesIfMissing = false);
 
 };
 
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 1ca4f7264..15a7c5809 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -14,7 +14,7 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 
 	// Skip the format hint if it is there.
 	buf = trimWhitespaces(buf);
-	if(buf[0] != '0') {
+	if(buf[0] < '0' || buf[0] > '9') {
 		buf = storm::parser::forwardToNextLine(buf, lineEndings);
 	}
 
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index d4ab649ba..5f6e13360 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -29,23 +29,23 @@ namespace parser {
 NondeterministicModelParserResultContainer<double> parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
 		std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-	NondeterministicSparseTransitionParserResult_t nondeterministicSparseTransitionParserResult(std::move(storm::parser::NondeterministicSparseTransitionParser(transitionSystemFile)));
-	storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(nondeterministicSparseTransitionParserResult.first));
+	NondeterministicSparseTransitionParser::Result transitionParserResult(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionSystemFile)));
+	storm::storage::SparseMatrix<double> transitions(std::move(transitionParserResult.transitionMatrix));
 
-	uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
-	uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
+	uint_fast64_t stateCount = transitions.getColumnCount();
+	uint_fast64_t rowCount = transitions.getRowCount();
 
-	storm::models::AtomicPropositionsLabeling resultLabeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
+	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
 
-	NondeterministicModelParserResultContainer<double> result(std::move(resultTransitionSystem), std::move(nondeterministicSparseTransitionParserResult.second), std::move(resultLabeling));
+	NondeterministicModelParserResultContainer<double> result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling));
 	
 	if (stateRewardFile != "") {
 		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
 	}
+
 	if (transitionRewardFile != "") {
-		RewardMatrixInformationStruct* rewardMatrixInfo = new RewardMatrixInformationStruct(rowCount, stateCount, &result.rowMapping);
-		result.transitionRewards.reset(storm::parser::NondeterministicSparseTransitionParser(transitionRewardFile, rewardMatrixInfo).first);
-		delete rewardMatrixInfo;
+		RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, &result.rowMapping);
+		result.transitionRewards.reset(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo).transitionMatrix);
 	}
 	return result;
 }
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 02a1e94f1..fa20585ec 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -1,5 +1,5 @@
 /*!
- *	TraParser.cpp
+ *	NondeterministicSparseTransitionParser.cpp
  *
  *	Created on: 20.11.2012
  *		Author: Gereon Kremer
@@ -7,380 +7,277 @@
 
 #include "src/parser/NondeterministicSparseTransitionParser.h"
 
-#include <errno.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <locale.h>
-
-#include <cstdlib>
-#include <cstdio>
-#include <cstring>
-#include <clocale>
-#include <iostream>
-#include <utility>
 #include <string>
 
 #include "src/settings/Settings.h"
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
-#include <cstdint>
+
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;
 
 namespace storm {
-namespace parser {
+	namespace parser {
 
-/*!
- *	@brief	Perform first pass through the file and obtain overall number of
- *	choices, number of non-zero cells and maximum node id.
- *
- *	This method does the first pass through the transition file.
- *
- *	It computes the overall number of nondeterministic choices, i.e. the
- *	number of rows in the matrix that should be created.
- *	It also calculates the overall number of non-zero cells, i.e. the number
- *	of elements the matrix has to hold, and the maximum node id, i.e. the
- *	number of columns of the matrix.
- *
- *	@param buf Data to scan. Is expected to be some char array.
- *	@param choices Overall number of choices.
- *	@param maxnode Is set to highest id of all nodes.
- *	@return The number of non-zero elements.
- */
-uint_fast64_t firstPass(char* buf, SupportedLineEndingsEnum lineEndings, uint_fast64_t& choices, int_fast64_t& maxnode, RewardMatrixInformationStruct* rewardMatrixInformation) {
-	bool isRewardFile = rewardMatrixInformation != nullptr;
-
-	/*
-	 *	Check file header and extract number of transitions.
-	 */
-	if (!isRewardFile) {
-		// skip format hint
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
-	}
-
-	/*
-	 *	Read all transitions.
-	 */
-	int_fast64_t source, target, choice, lastchoice = -1;
-	int_fast64_t lastsource = -1;
-	uint_fast64_t nonzero = 0;
-	double val;
-	choices = 0;
-	maxnode = 0;
-	while (buf[0] != '\0') {
-		/*
-		 *	Read source state and choice.
-		 */
-		source = checked_strtol(buf, &buf);
-
-		// Read the name of the nondeterministic choice.
-		choice = checked_strtol(buf, &buf);
-
-		// Check if we encountered a state index that is bigger than all previously seen.
-		if (source > maxnode) {
-			maxnode = source;
+		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitions(std::string const& filename) {
+
+			RewardMatrixInformationStruct nullInformation;
+
+			return NondeterministicSparseTransitionParser::parse(filename, false, nullInformation);
 		}
 
-		if (isRewardFile) {
-			// If we have switched the source state, we possibly need to insert the rows of the last
-			// last source state.
-			if (source != lastsource && lastsource != -1) {
-				choices += lastchoice - ((*rewardMatrixInformation->nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation->nondeterministicChoiceIndices)[lastsource] - 1);
-			}
+		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
 
-			// If we skipped some states, we need to reserve empty rows for all their nondeterministic
-			// choices.
-			for (int_fast64_t i = lastsource + 1; i < source; ++i) {
-				choices += ((*rewardMatrixInformation->nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation->nondeterministicChoiceIndices)[i]);
-			}
+			return NondeterministicSparseTransitionParser::parse(filename, true, rewardMatrixInformation);
+		}
 
-			// If we advanced to the next state, but skipped some choices, we have to reserve rows
-			// for them
-			if (source != lastsource) {
-				choices += choice + 1;
-			} else if (choice != lastchoice) {
-				choices += choice - lastchoice;
-			}
-		} else {
-			// If we have skipped some states, we need to reserve the space for the self-loop insertion
-			// in the second pass.
-			if (source > lastsource + 1) {
-				nonzero += source - lastsource - 1;
-				choices += source - lastsource - 1;
-			} else if (source != lastsource || choice != lastchoice) {
-				// If we have switched the source state or the nondeterministic choice, we need to
-				// reserve one row more.
-				++choices;
+		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+
+			// Check file header and extract number of transitions.
+
+			// Skip the format hint if it is there.
+			buf = trimWhitespaces(buf);
+			if(buf[0] < '0' || buf[0] > '9') {
+				buf = storm::parser::forwardToNextLine(buf, lineEndings);
 			}
-		}
 
-		// Read target and check if we encountered a state index that is bigger than all previously
-		// seen.
-		target = checked_strtol(buf, &buf);
-		if (target > maxnode) {
-			maxnode = target;
-		}
+			// Read all transitions.
+			uint_fast64_t source = 0, target = 0, choice = 0, lastchoice = 0, lastsource = 0;
+			double val = 0.0;
+			NondeterministicSparseTransitionParser::FirstPassResult result;
 
-		// Read value and check whether it's positive.
-		val = checked_strtod(buf, &buf);
-		if ((val < 0.0) || (val > 1.0)) {
-			LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
-			return 0;
-		}
+			// Since the first line is already a new choice but is not covered below, that has to be covered here.
+			result.choices = 1;
 
-		lastchoice = choice;
-		lastsource = source;
-
-		/*
-		 *	Increase number of non-zero values.
-		 */
-		nonzero++;
-
-		// The PRISM output format lists the name of the transition in the fourth column,
-		// but omits the fourth column if it is an internal action. In either case, however, the third column
-		// is followed by a space. We need to skip over that space first (instead of trimming whitespaces),
-		// before we can skip to the line end, because trimming the white spaces will proceed to the next line
-		// in case there is no action label in the fourth column.
-		if (buf[0] == ' ') {
-			++buf;
-		}
+			while (buf[0] != '\0') {
 
-		/*
-		 *	Proceed to beginning of next line.
-		 */
-		switch (lineEndings) {
-			case SupportedLineEndingsEnum::SlashN:
-				buf += strcspn(buf, " \t\n");
-				break;
-			case SupportedLineEndingsEnum::SlashR:
-				buf += strcspn(buf, " \t\r");
-				break;
-			case SupportedLineEndingsEnum::SlashRN:
-				buf += strcspn(buf, " \t\r\n");
-				break;
-			default:
-			case storm::parser::SupportedLineEndingsEnum::Unsupported:
-				// This Line will never be reached as the Parser would have thrown already.
-				throw;
-				break;
-		}
-		buf = trimWhitespaces(buf);
-	}
+				// Read source state and choice.
+				source = checked_strtol(buf, &buf);
 
-	if (isRewardFile) {
-		// If not all rows were filled for the last state, we need to insert them.
-		choices += lastchoice - ((*rewardMatrixInformation->nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation->nondeterministicChoiceIndices)[lastsource] - 1);
+				// Read the name of the nondeterministic choice.
+				choice = checked_strtol(buf, &buf);
 
-		// If we skipped some states, we need to reserve empty rows for all their nondeterministic
-		// choices.
-		for (uint_fast64_t i = lastsource + 1; i < rewardMatrixInformation->nondeterministicChoiceIndices->size() - 1; ++i) {
-			choices += ((*rewardMatrixInformation->nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation->nondeterministicChoiceIndices)[i]);
-		}
-	}
+				// Check if we encountered a state index that is bigger than all previously seen.
+				if (source > result.highestStateIndex) {
+					result.highestStateIndex = source;
+				}
 
-	return nonzero;
-}
+				if (isRewardFile) {
+					// If we have switched the source state, we possibly need to insert rows for skipped choices of the last
+					// source state.
+					if (source != lastsource) {
+						// number of choices skipped = number of choices of last state - number of choices read
+						result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource]) - (lastchoice + 1);
+					}
+
+					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
+					// choices.
+					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
+						result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[i]);
+					}
+
+					// If we advanced to the next state, but skipped some choices, we have to reserve rows
+					// for them.
+					if (source != lastsource) {
+						result.choices += choice + 1;
+					} else if (choice != lastchoice) {
+						result.choices += choice - lastchoice;
+					}
+				} else {
 
+					// If we have skipped some states, we need to reserve the space for the self-loop insertion
+					// in the second pass.
+					if (source > lastsource + 1) {
+						result.numberOfNonzeroEntries += source - lastsource - 1;
+						result.choices += source - lastsource - 1;
+					} else if (source != lastsource || choice != lastchoice) {
+						// If we have switched the source state or the nondeterministic choice, we need to
+						// reserve one row more.
+						++result.choices;
+					}
+				}
 
+				// Read target and check if we encountered a state index that is bigger than all previously
+				// seen.
+				target = checked_strtol(buf, &buf);
+				if (target > result.highestStateIndex) {
+					result.highestStateIndex = target;
+				}
 
-/*!
- *	Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
- *
- *	Matrices created with this method have to be freed with the delete operator.
- *	@param filename input .tra file's name.
- *	@return a pointer to the created sparse matrix.
- */
+				// Read value and check whether it's positive.
+				val = checked_strtod(buf, &buf);
+				if ((val < 0.0) || (val > 1.0)) {
+					LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
+					NondeterministicSparseTransitionParser::FirstPassResult nullResult;
+					return nullResult;
+				}
 
-NondeterministicSparseTransitionParserResult_t NondeterministicSparseTransitionParser(std::string const &filename, RewardMatrixInformationStruct* rewardMatrixInformation) {
-	/*
-	 *	Enforce locale where decimal point is '.'.
-	 */
-	setlocale(LC_NUMERIC, "C");
-
-	if (!fileExistsAndIsReadable(filename.c_str())) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-		throw storm::exceptions::WrongFormatException();
-	}
-
-	bool isRewardFile = rewardMatrixInformation != nullptr;
-
-	/*
-	 *	Find out about the used line endings.
-	 */
-	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
-
-	/*
-	 *	Open file.
-	 */
-	MappedFile file(filename.c_str());
-	char* buf = file.data;
-
-	/*
-	 *	Perform first pass, i.e. obtain number of columns, rows and non-zero elements.
-	 */
-	int_fast64_t maxnode;
-	uint_fast64_t choices;
-	uint_fast64_t nonzero = firstPass(file.data, lineEndings, choices, maxnode, rewardMatrixInformation);
-
-	/*
-	 *	If first pass returned zero, the file format was wrong.
-	 */
-	if (nonzero == 0) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format.");
-		throw storm::exceptions::WrongFormatException();
-	}
-
-	/*
-	 *	Perform second pass.
-	 *	
-	 *	From here on, we already know that the file header is correct.
-	 */
-
-	/*
-	 *	Skip file header.
-	 */
-	if (!isRewardFile) {
-		// skip format hint
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
-	}
-
-	if (isRewardFile) {
-		if (choices > rewardMatrixInformation->rowCount || (uint_fast64_t)(maxnode + 1) > rewardMatrixInformation->columnCount) {
-			LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size.");
-			throw storm::exceptions::WrongFormatException() << "Reward matrix size exceeds transition matrix size.";
-		} else if (choices != rewardMatrixInformation->rowCount) {
-			LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count.");
-			throw storm::exceptions::WrongFormatException() << "Reward matrix row count does not match transition matrix row count.";
-		} else {
-			maxnode = rewardMatrixInformation->columnCount - 1;
-		}
-	}
-
-	/*
-	 *	Create and initialize matrix.
-	 *	The matrix should have as many columns as we have nodes and as many rows as we have choices.
-	 *	Those two values, as well as the number of nonzero elements, was been calculated in the first run.
-	 */
-	LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << choices << " x " << (maxnode+1) << " with " << nonzero << " entries.");
-	storm::storage::SparseMatrixBuilder<double> matrixBuilder(choices, maxnode + 1, nonzero);
-
-	/*
-	 *	Create row mapping.
-	 */
-	std::vector<uint_fast64_t> rowMapping(maxnode + 2, 0);
-
-	/*
-	 *	Parse file content.
-	 */
-	int_fast64_t source, target, lastsource = -1, choice, lastchoice = -1;
-	uint_fast64_t curRow = -1;
-	double val;
-	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-	bool hadDeadlocks = false;
-
-	/*
-	 *	Read all transitions from file.
-	 */
-	while (buf[0] != '\0') {
-		/*
-		 *	Read source state and choice.
-		 */
-		source = checked_strtol(buf, &buf);
-		choice = checked_strtol(buf, &buf);
-
-		if (isRewardFile) {
-			// If we have switched the source state, we possibly need to insert the rows of the last
-			// last source state.
-			if (source != lastsource && lastsource != -1) {
-				curRow += lastchoice - ((*rewardMatrixInformation->nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation->nondeterministicChoiceIndices)[lastsource] - 1);
+				lastchoice = choice;
+				lastsource = source;
+
+				// Increase number of non-zero values.
+				result.numberOfNonzeroEntries++;
+
+				// The PRISM output format lists the name of the transition in the fourth column,
+				// but omits the fourth column if it is an internal action. In either case we can skip to the end of the line.
+				buf = forwardToLineEnd(buf, lineEndings);
+
+				buf = trimWhitespaces(buf);
 			}
 
-			// If we skipped some states, we need to reserve empty rows for all their nondeterministic
-			// choices.
-			for (int_fast64_t i = lastsource + 1; i < source; ++i) {
-				curRow += ((*rewardMatrixInformation->nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation->nondeterministicChoiceIndices)[i]);
+			if (isRewardFile) {
+				// If not all rows were filled for the last state, we need to insert them.
+				result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource] ) - (lastchoice + 1);
+
+				// If we skipped some states, we need to reserve empty rows for all their nondeterministic
+				// choices.
+				for (uint_fast64_t i = lastsource + 1; i < rewardMatrixInformation.nondeterministicChoiceIndices->size() - 1; ++i) {
+					result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[i]);
+				}
 			}
 
-			// If we advanced to the next state, but skipped some choices, we have to reserve rows
-			// for them
-			if (source != lastsource) {
-				curRow += choice + 1;
-			} else if (choice != lastchoice) {
-				curRow += choice - lastchoice;
+			return result;
+		}
+
+		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parse(std::string const &filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+
+			// Enforce locale where decimal point is '.'.
+			setlocale(LC_NUMERIC, "C");
+
+			if (!fileExistsAndIsReadable(filename.c_str())) {
+				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+				throw storm::exceptions::WrongFormatException();
 			}
-		} else {
-			// Increase line count if we have either finished reading the transitions of a certain state
-			// or we have finished reading one nondeterministic choice of a state.
-			if ((source != lastsource || choice != lastchoice)) {
-				++curRow;
+
+			// Find out about the used line endings.
+			SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+
+			// Open file.
+			MappedFile file(filename.c_str());
+			char* buf = file.data;
+
+			// Perform first pass, i.e. obtain number of columns, rows and non-zero elements.
+			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.data, lineEndings, isRewardFile, rewardMatrixInformation);
+
+			// If first pass returned zero, the file format was wrong.
+			if (firstPass.numberOfNonzeroEntries == 0) {
+				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format.");
+				throw storm::exceptions::WrongFormatException();
 			}
-			/*
-			 *	Check if we have skipped any source node, i.e. if any node has no
-			 *	outgoing transitions. If so, insert a self-loop.
-			 *	Also add self-loops to rowMapping.
-			 */
-			for (int_fast64_t node = lastsource + 1; node < source; node++) {
-				hadDeadlocks = true;
-				if (fixDeadlocks) {
-					rowMapping.at(node) = curRow;
-					matrixBuilder.addNextValue(curRow, node, 1);
-					++curRow;
-					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted.");
+
+			// Perform second pass.
+
+			// Skip the format hint if it is there.
+			buf = trimWhitespaces(buf);
+			if(buf[0] < '0' || buf[0] > '9') {
+				buf = storm::parser::forwardToNextLine(buf, lineEndings);
+			}
+
+			if (isRewardFile) {
+				// The reward matrix should match the size of the transition matrix.
+				if (firstPass.choices > rewardMatrixInformation.rowCount || (uint_fast64_t)(firstPass.highestStateIndex + 1) > rewardMatrixInformation.columnCount) {
+					LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size.");
+					throw storm::exceptions::WrongFormatException() << "Reward matrix size exceeds transition matrix size.";
+				} else if (firstPass.choices != rewardMatrixInformation.rowCount) {
+					LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count.");
+					throw storm::exceptions::WrongFormatException() << "Reward matrix row count does not match transition matrix row count.";
 				} else {
-					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": node " << node << " has no outgoing transitions.");
+					firstPass.highestStateIndex = rewardMatrixInformation.columnCount - 1;
 				}
 			}
-			if (source != lastsource) {
-				/*
-				 *	Add this source to rowMapping, if this is the first choice we encounter for this state.
-				 */
-				rowMapping.at(source) = curRow;
-			}
-		}
 
-		// Read target and value and write it to the matrix.
-		target = checked_strtol(buf, &buf);
-		val = checked_strtod(buf, &buf);
-		matrixBuilder.addNextValue(curRow, target, val);
 
-		lastsource = source;
-		lastchoice = choice;
+			// Create the matrix builder.
+			// The matrix to be build should have as many columns as we have nodes and as many rows as we have choices.
+			// Those two values, as well as the number of nonzero elements, was been calculated in the first run.
+			LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << firstPass.choices << " x " << (firstPass.highestStateIndex+1) << " with " << firstPass.numberOfNonzeroEntries << " entries.");
+			storm::storage::SparseMatrixBuilder<double> matrixBuilder(firstPass.choices, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
+
+			// Create row mapping.
+			std::vector<uint_fast64_t> rowMapping(firstPass.highestStateIndex + 2, 0);
+
+			// Initialize variables for the parsing run.
+			uint_fast64_t source = 0, target = 0, lastsource = 0, choice = 0, lastchoice = 0, curRow = 0;
+			double val = 0.0;
+			bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+			bool hadDeadlocks = false;
+
+			// Read all transitions from file.
+			while (buf[0] != '\0') {
+
+				// Read source state and choice.
+				source = checked_strtol(buf, &buf);
+				choice = checked_strtol(buf, &buf);
+
+				if (isRewardFile) {
+					// If we have switched the source state, we possibly need to insert the rows of the last
+					// source state.
+					if (source != lastsource) {
+						curRow += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource]) -(lastchoice + 1);
+					}
+
+					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
+					// choices.
+					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
+						curRow += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[i]);
+					}
+
+					// If we advanced to the next state, but skipped some choices, we have to reserve rows
+					// for them
+					if (source != lastsource) {
+						curRow += choice + 1;
+					} else if (choice != lastchoice) {
+						curRow += choice - lastchoice;
+					}
+				} else {
+					// Increase line count if we have either finished reading the transitions of a certain state
+					// or we have finished reading one nondeterministic choice of a state.
+					if ((source != lastsource || choice != lastchoice)) {
+						++curRow;
+					}
+					// Check if we have skipped any source node, i.e. if any node has no
+					// outgoing transitions. If so, insert a self-loop.
+					// Also add self-loops to rowMapping.
+					for (uint_fast64_t node = lastsource + 1; node < source; node++) {
+						hadDeadlocks = true;
+						if (fixDeadlocks) {
+							rowMapping.at(node) = curRow;
+							matrixBuilder.addNextValue(curRow, node, 1);
+							++curRow;
+							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted.");
+						} else {
+							LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": node " << node << " has no outgoing transitions.");
+						}
+					}
+					if (source != lastsource) {
+						// Add this source to rowMapping, if this is the first choice we encounter for this state.
+						rowMapping.at(source) = curRow;
+					}
+				}
 
-		/*
-		 *	Proceed to beginning of next line in file and next row in matrix.
-		 */
-		if (buf[0] == ' ') {
-			++buf;
-		}
-		switch (lineEndings) {
-			case SupportedLineEndingsEnum::SlashN:
-				buf += strcspn(buf, " \t\n");
-				break;
-			case SupportedLineEndingsEnum::SlashR:
-				buf += strcspn(buf, " \t\r");
-				break;
-			case SupportedLineEndingsEnum::SlashRN:
-				buf += strcspn(buf, " \t\r\n");
-				break;
-			default:
-			case storm::parser::SupportedLineEndingsEnum::Unsupported:
-				// This Line will never be reached as the Parser would have thrown already.
-				throw;
-				break;
-		}
-		buf = trimWhitespaces(buf);
-	}
+				// Read target and value and write it to the matrix.
+				target = checked_strtol(buf, &buf);
+				val = checked_strtod(buf, &buf);
+				matrixBuilder.addNextValue(curRow, target, val);
+
+				lastsource = source;
+				lastchoice = choice;
 
-	for (int_fast64_t node = lastsource + 1; node <= maxnode + 1; node++) {
-		rowMapping.at(node) = curRow + 1;
-	}
+				// Proceed to beginning of next line in file and next row in matrix.
+				buf = forwardToLineEnd(buf, lineEndings);
 
-	if (!fixDeadlocks && hadDeadlocks && !isRewardFile) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
+				buf = trimWhitespaces(buf);
+			}
 
-	return std::make_pair(matrixBuilder.build(), std::move(rowMapping));
-}
+			for (uint_fast64_t node = lastsource + 1; node <= firstPass.highestStateIndex + 1; node++) {
+				rowMapping.at(node) = curRow + 1;
+			}
+
+			if (!fixDeadlocks && hadDeadlocks && !isRewardFile) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
+
+			return NondeterministicSparseTransitionParser::Result(matrixBuilder.build(), rowMapping);
+		}
 
-}  // namespace parser
+	}  // namespace parser
 }  // namespace storm
diff --git a/src/parser/NondeterministicSparseTransitionParser.h b/src/parser/NondeterministicSparseTransitionParser.h
index 900bc088e..34fc3f397 100644
--- a/src/parser/NondeterministicSparseTransitionParser.h
+++ b/src/parser/NondeterministicSparseTransitionParser.h
@@ -1,30 +1,101 @@
-#ifndef STORM_PARSER_NONDETTRAPARSER_H_
-#define STORM_PARSER_NONDETTRAPARSER_H_
-
-#include "src/storage/SparseMatrix.h"
+#ifndef STORM_PARSER_NONDETERMINISTICSPARSETRANSITIONPARSER_H_
+#define STORM_PARSER_NONDETERMINISTICSPARSETRANSITIONPARSER_H_
 
 #include "src/parser/Parser.h"
-#include "src/utility/OsDetection.h"
+#include "src/storage/SparseMatrix.h"
 
-#include <utility>
-#include <memory>
 #include <vector>
 
 namespace storm {
-namespace parser {
+	namespace parser {
+
+		class NondeterministicSparseTransitionParser {
+
+		public:
+
+			/*
+			 * A structure representing the result of the first pass of this parser.
+			 * It contains the number of non-zero entries in the model, the highest state index and the total number if nondeterministic choices.
+			 */
+			struct FirstPassResult {
+
+				FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0), choices(0) {
+					// Intentionally left empty.
+				}
+
+				// The total number of non-zero entries of the model.
+				uint_fast64_t numberOfNonzeroEntries;
+
+				// The highest state index that appears in the model.
+				uint_fast64_t highestStateIndex;
+
+				// The total number of nondeterministic choices within the transition system.
+				uint_fast64_t choices;
+			};
+
+			/*!
+			 * A structure representing the result of the parser.
+			 * It contains the resulting matrix as well as the row mapping.
+			 */
+			struct Result {
+
+				Result(storm::storage::SparseMatrix<double> transitionMatrix, std::vector<uint_fast64_t> rowMapping) : transitionMatrix(transitionMatrix), rowMapping(rowMapping) {
+					// Intentionally left empty.
+				}
+
+				// The matrix containing the parsed transition system.
+				storm::storage::SparseMatrix<double> transitionMatrix;
+
+				// A mapping from rows of the matrix to states of the model.
+				// This resolves the nondeterministic choices inside the transition system.
+				std::vector<uint_fast64_t> rowMapping;
+			};
+
+			/*!
+			 *	@brief	Load a nondeterministic transition system from file and create a
+			 *	sparse adjacency matrix whose entries represent the weights of the edges
+			 */
+			static Result parseNondeterministicTransitions(std::string const &filename);
+
+			/*!
+			 *	@brief	Load a nondeterministic transition system from file and create a
+			 *	sparse adjacency matrix whose entries represent the weights of the edges
+			 */
+			static Result parseNondeterministicTransitionRewards(std::string const &filename, RewardMatrixInformationStruct const& rewardMatrixInformation);
+
+		private:
+
+			/*!
+			 * This method does the first pass through the buffer containing the content of some transition file.
+			 *
+			 * It computes the overall number of nondeterministic choices, i.e. the
+			 * number of rows in the matrix that should be created.
+			 * It also calculates the overall number of non-zero cells, i.e. the number
+			 * of elements the matrix has to hold, and the maximum node id, i.e. the
+			 * number of columns of the matrix.
+			 *
+			 * @param buffer Buffer containing the data to scan. This is expected to be some char array.
+			 * @param lineEndings The line endings that are to be used while parsing.
+			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+			 * @return A structure representing the result of the first pass.
+			 */
+			static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation);
+
+			/*!
+			 * The main parsing routine.
+			 * Opens the given file, calls the first pass and performs the second pass, parsing the content of the file into a SparseMatrix.
+			 *
+			 * @param filename The path of file to be parsed.
+			 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
+			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+			 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
+			 * @return A SparseMatrix containing the parsed file contents.
+			 */
+			static Result parse(std::string const& filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation);
+
+		};
 	
-/*! 
- * @brief Contains the Result of a call to the NondeterministicSparseTransitionParser function. The first part is the resulting matrix. The second part is the row mapping.
- */
-typedef std::pair<storm::storage::SparseMatrix<double>, std::vector<uint_fast64_t>> NondeterministicSparseTransitionParserResult_t;
-
-/*!
- *	@brief	Load a nondeterministic transition system from file and create a
- *	sparse adjacency matrix whose entries represent the weights of the edges
- */
-NondeterministicSparseTransitionParserResult_t NondeterministicSparseTransitionParser(std::string const &filename, RewardMatrixInformationStruct* rewardMatrixInformation = nullptr);
-
-} // namespace parser
+	} // namespace parser
 } // namespace storm
 
-#endif /* STORM_PARSER_NONDETTRAPARSER_H_ */
+#endif /* STORM_PARSER_NONDETERMINISTICSPARSETRANSITIONPARSER_H__H_ */
diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp
index 6fb26ef4b..b1b0c6e79 100644
--- a/src/parser/Parser.cpp
+++ b/src/parser/Parser.cpp
@@ -117,6 +117,29 @@ SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool t
 	return SupportedLineEndingsEnum::Unsupported;
 }
 
+/*!
+ * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
+ */
+char* forwardToLineEnd(char* buffer, SupportedLineEndingsEnum lineEndings) {
+	switch (lineEndings) {
+		case SupportedLineEndingsEnum::SlashN:
+			return buffer + strcspn(buffer, "\n\0");
+			break;
+		case SupportedLineEndingsEnum::SlashR:
+			return buffer + strcspn(buffer, "\r\0");
+			break;
+		case SupportedLineEndingsEnum::SlashRN:
+			return buffer + strcspn(buffer, "\r\0");
+			break;
+		default:
+		case SupportedLineEndingsEnum::Unsupported:
+			// This Line will never be reached as the Parser would have thrown already.
+			throw;
+			break;
+	}
+	return nullptr;
+}
+
 /*!
  * @brief Encapsulates the usage of function @strchr to forward to the next line
  */
diff --git a/src/parser/Parser.h b/src/parser/Parser.h
index e7fcf4dab..b2cfb0677 100644
--- a/src/parser/Parser.h
+++ b/src/parser/Parser.h
@@ -146,6 +146,11 @@ enum class SupportedLineEndingsEnum : unsigned short {
  */
 storm::parser::SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false);
 
+/*!
+ * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
+ */
+char* forwardToLineEnd(char* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+
 /*!
  * @brief Encapsulates the usage of function @strchr to forward to the next line
  */

From c279c693e55acc71265298ac0bea881c0810b3cd Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 8 Jan 2014 00:06:04 +0100
Subject: [PATCH 009/147] Refactored NondeterministicModelParser.h/.cpp

-Mostly restruturing and tidying up.

Next up: Refatoring AtomicPropositionLabelingParser.h/.cpp


Former-commit-id: c26abad85032afa07e5105812c73992fc3cf4b27
---
 src/parser/AutoParser.h                    |   4 +-
 src/parser/DeterministicModelParser.cpp    |  10 +-
 src/parser/DeterministicModelParser.h      |   8 +-
 src/parser/NondeterministicModelParser.cpp | 113 +++++++++++----------
 src/parser/NondeterministicModelParser.h   |  96 +++++++++--------
 test/functional/parser/ParseMdpTest.cpp    |   2 +-
 6 files changed, 125 insertions(+), 108 deletions(-)

diff --git a/src/parser/AutoParser.h b/src/parser/AutoParser.h
index cec1fad66..59082a135 100644
--- a/src/parser/AutoParser.h
+++ b/src/parser/AutoParser.h
@@ -56,11 +56,11 @@ class AutoParser {
 					break;
 				}
 				case storm::models::MDP: {
-					this->model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParserAsMdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					this->model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParser::parseMdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
 					break;
 				}
 				case storm::models::CTMDP: {
-					this->model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParserAsCtmdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					this->model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParser::parseCtmdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
 					break;
 				}
                 case storm::models::MA: {
diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index c7411b14f..3f25b9c0c 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -26,16 +26,16 @@ namespace parser {
  * @param stateRewardFile String containing the location of the state reward file (...srew)
  * @param transitionRewardFile String containing the location of the transition reward file (...trew)
  */
-DeterministicModelParser::ResultContainer DeterministicModelParser::parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+DeterministicModelParser::Result DeterministicModelParser::parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
 	storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionSystemFile)));
 
 	uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
 	uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
 
-	storm::models::AtomicPropositionsLabeling resultLabeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
+	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
 
-	DeterministicModelParser::ResultContainer result(std::move(resultTransitionSystem), std::move(resultLabeling));
+	DeterministicModelParser::Result result(std::move(resultTransitionSystem), std::move(labeling));
 
 	// Only parse state rewards of a file is given.
 	if (stateRewardFile != "") {
@@ -58,7 +58,7 @@ DeterministicModelParser::ResultContainer DeterministicModelParser::parseDetermi
  */
 storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-	DeterministicModelParser::ResultContainer parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
+	DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
 	return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 }
 
@@ -69,7 +69,7 @@ storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string cons
  */
 storm::models::Ctmc<double> DeterministicModelParser::parseCtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-	DeterministicModelParser::ResultContainer parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
+	DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
 	return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 }
 
diff --git a/src/parser/DeterministicModelParser.h b/src/parser/DeterministicModelParser.h
index c6b64b6c1..3fc840c5e 100644
--- a/src/parser/DeterministicModelParser.h
+++ b/src/parser/DeterministicModelParser.h
@@ -35,13 +35,13 @@ public:
 	/*!
 	 * @brief A struct containing the parsed components of a deterministic model.
 	 */
-	struct ResultContainer {
+	struct Result {
 
-		ResultContainer(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
+		Result(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
 			// Intentionally left empty.
 		}
 
-		ResultContainer(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
+		Result(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
 			// Intentionally left empty.
 		}
 
@@ -80,7 +80,7 @@ private:
 	/*!
 	 * @brief Call sub-parsers on the given files and fill the container with the results.
 	 */
-	static ResultContainer parseDeterministicModel(std::string const & transitionSystemFile,
+	static Result parseDeterministicModel(std::string const & transitionSystemFile,
 												   std::string const & labelingFile,
 												   std::string const & stateRewardFile = "",
 												   std::string const & transitionRewardFile = "");
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index 5f6e13360..fd2e85912 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -15,63 +15,64 @@
 #include "src/parser/SparseStateRewardParser.h"
 
 namespace storm {
-namespace parser {
+	namespace parser {
 
-/*!
- * Parses a transition file and a labeling file and produces an intermediate Result Container
- * Note that the labeling file may have at most as many nodes as the transition file!
- *
- * @param transitionSystemFile String containing the location of the transition file (....tra)
- * @param labelingFile String containing the location of the labeling file (....lab)
- * @param stateRewardFile String containing the location of the state reward file (...srew)
- * @param transitionRewardFile String containing the location of the transition reward file (...trew)
- */
-NondeterministicModelParserResultContainer<double> parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
-		std::string const & stateRewardFile, std::string const & transitionRewardFile) {
-
-	NondeterministicSparseTransitionParser::Result transitionParserResult(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionSystemFile)));
-	storm::storage::SparseMatrix<double> transitions(std::move(transitionParserResult.transitionMatrix));
-
-	uint_fast64_t stateCount = transitions.getColumnCount();
-	uint_fast64_t rowCount = transitions.getRowCount();
-
-	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
-
-	NondeterministicModelParserResultContainer<double> result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling));
-	
-	if (stateRewardFile != "") {
-		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
-	}
-
-	if (transitionRewardFile != "") {
-		RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, &result.rowMapping);
-		result.transitionRewards.reset(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo).transitionMatrix);
-	}
-	return result;
-}
-
-/*!
- * Uses the Function parseNondeterministicModel internally to parse the given input files.
- * @note This is a Short-Hand for Constructing a Mdp directly from the data returned by @parseNondeterministicModel
- * @return A Mdp Model
- */
-storm::models::Mdp<double> NondeterministicModelParserAsMdp(std::string const & transitionSystemFile, std::string const & labelingFile,
-														 std::string const & stateRewardFile, std::string const & transitionRewardFile) {
-	NondeterministicModelParserResultContainer<double> parserResult = parseNondeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile);
-	return storm::models::Mdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
-}
-
-/*!
- * Uses the Function parseNondeterministicModel internally to parse the given input files.
- * @note This is a Short-Hand for Constructing a Ctmdp directly from the data returned by @parseNondeterministicModel
- * @return A Ctmdp Model
- */
-storm::models::Ctmdp<double> NondeterministicModelParserAsCtmdp(std::string const & transitionSystemFile, std::string const & labelingFile,
-															 std::string const & stateRewardFile, std::string const & transitionRewardFile) {
-	NondeterministicModelParserResultContainer<double> parserResult = parseNondeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile);
-	return storm::models::Ctmdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
-}
+		/*!
+		 * Parses a transition file and a labeling file and produces an intermediate Result Container
+		 * Note that the labeling file may have at most as many nodes as the transition file!
+		 *
+		 * @param transitionSystemFile String containing the location of the transition file (....tra)
+		 * @param labelingFile String containing the location of the labeling file (....lab)
+		 * @param stateRewardFile String containing the location of the state reward file (...srew)
+		 * @param transitionRewardFile String containing the location of the transition reward file (...trew)
+		 */
+		NondeterministicModelParser::Result NondeterministicModelParser::parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
+				std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+
+			NondeterministicSparseTransitionParser::Result transitionParserResult(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionSystemFile)));
+			storm::storage::SparseMatrix<double> transitions(std::move(transitionParserResult.transitionMatrix));
+
+			uint_fast64_t stateCount = transitions.getColumnCount();
+			uint_fast64_t rowCount = transitions.getRowCount();
+
+			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
+
+			Result result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling));
+
+			// Only parse state rewards of a file is given.
+			if (stateRewardFile != "") {
+				result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
+			}
+
+			// Only parse transition rewards of a file is given.
+			if (transitionRewardFile != "") {
+				RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, &result.rowMapping);
+				result.transitionRewards.reset(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo).transitionMatrix);
+			}
+			return result;
+		}
+
+		/*!
+		 * Uses the Function parseNondeterministicModel internally to parse the given input files.
+		 * @note This is a Short-Hand for Constructing a Mdp directly from the data returned by @parseNondeterministicModel
+		 * @return A Mdp Model
+		 */
+		storm::models::Mdp<double> NondeterministicModelParser::parseMdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+
+			Result parserResult = parseNondeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile);
+			return storm::models::Mdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+		}
+
+		/*!
+		 * Uses the Function parseNondeterministicModel internally to parse the given input files.
+		 * @note This is a Short-Hand for Constructing a Ctmdp directly from the data returned by @parseNondeterministicModel
+		 * @return A Ctmdp Model
+		 */
+		storm::models::Ctmdp<double> NondeterministicModelParser::parseCtmdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-} /* namespace parser */
+			Result parserResult = parseNondeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile);
+			return storm::models::Ctmdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+		}
 
+	} /* namespace parser */
 } /* namespace storm */
diff --git a/src/parser/NondeterministicModelParser.h b/src/parser/NondeterministicModelParser.h
index 449a9b162..6719a4585 100644
--- a/src/parser/NondeterministicModelParser.h
+++ b/src/parser/NondeterministicModelParser.h
@@ -13,52 +13,68 @@
 #include "src/models/Ctmdp.h"
 
 namespace storm {
+	namespace parser {
 
-namespace parser {
+		class NondeterministicModelParser {
 
-/*!
- *	@brief Load label and transition file and return initialized mdp object
- *
- *	@note This class creates a new Mdp object that can
- *	be accessed via getMdp(). However, it will not delete this object!
- *
- *	@note The labeling representation in the file may use at most as much nodes as are specified in the mdp.
- */
+		public:
 
-storm::models::Mdp<double> NondeterministicModelParserAsMdp(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
-storm::models::Ctmdp<double> NondeterministicModelParserAsCtmdp(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+			/*!
+			 * @brief This Class acts as a container much like std::pair for the five return values of the NondeterministicModelParser
+			 */
+			struct Result {
 
+				Result(storm::storage::SparseMatrix<double>& transitionSystem, std::vector<uint_fast64_t>& rowMapping, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling), rowMapping(rowMapping) {
+					// Intentionally left empty.
+				}
 
-/*!
- * @brief This Class acts as a container much like std::pair for the five return values of the NondeterministicModelParser
- */
-template <class T>
-class NondeterministicModelParserResultContainer {
-public:
-	storm::storage::SparseMatrix<T> transitionSystem;
-	storm::models::AtomicPropositionsLabeling labeling;
-	std::vector<uint_fast64_t> rowMapping;
-	boost::optional<std::vector<T>> stateRewards;
-	boost::optional<storm::storage::SparseMatrix<T>> transitionRewards;
-	NondeterministicModelParserResultContainer(storm::storage::SparseMatrix<T>& transitionSystem, std::vector<uint_fast64_t>& rowMapping, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling), rowMapping(rowMapping) { }
-	NondeterministicModelParserResultContainer(storm::storage::SparseMatrix<T>&& transitionSystem, std::vector<uint_fast64_t>&& rowMapping, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)), rowMapping(std::move(rowMapping)) { }
-
-	NondeterministicModelParserResultContainer(const NondeterministicModelParserResultContainer & other) : transitionSystem(other.transitionSystem), 
-		labeling(other.labeling), rowMapping(other.rowMapping), stateRewards(other.stateRewards), transitionRewards(other.transitionRewards) {}
-	NondeterministicModelParserResultContainer(NondeterministicModelParserResultContainer && other) : transitionSystem(std::move(other.transitionSystem)), 
-		labeling(std::move(other.labeling)), rowMapping(std::move(other.rowMapping)), stateRewards(std::move(other.stateRewards)), transitionRewards(std::move(other.transitionRewards)) {}
-private:
-	NondeterministicModelParserResultContainer() {}
-};
-
-
-NondeterministicModelParserResultContainer<double> parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
-
-} /* namespace parser */
+				Result(storm::storage::SparseMatrix<double>&& transitionSystem, std::vector<uint_fast64_t>&& rowMapping, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)), rowMapping(std::move(rowMapping)) {
+					// Intentionally left empty.
+				}
+
+				// A matrix representing the transitions of the model
+				storm::storage::SparseMatrix<double> transitionSystem;
+
+				// The labels of each state.
+				storm::models::AtomicPropositionsLabeling labeling;
+
+				// A mapping from rows of the matrix to states of the model.
+				// This resolves the nondeterministic choices inside the transition system.
+				std::vector<uint_fast64_t> rowMapping;
+
+				// Optional rewards for each state.
+				boost::optional<std::vector<double>> stateRewards;
+
+				// Optional rewards for each transition.
+				boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
+			};
+
+			/*!
+			 *	@brief Load label and transition file and return initialized Mdp object
+			 *
+			 *	@note This class creates a new Mdp object that can
+			 *	be accessed via getMdp(). However, it will not delete this object!
+			 *
+			 *	@note The labeling representation in the file may use at most as much nodes as are specified in the mdp.
+			 */
+			static storm::models::Mdp<double> parseMdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+
+
+			/*!
+			 *
+			 */
+			static storm::models::Ctmdp<double> parseCtmdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+
+		private:
+
+			/*!
+			 *
+			 */
+			static Result parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+
+		};
 
+	} /* namespace parser */
 } /* namespace storm */
 
 #endif /* STORM_PARSER_NONDETERMINISTICMODELPARSER_H_ */
diff --git a/test/functional/parser/ParseMdpTest.cpp b/test/functional/parser/ParseMdpTest.cpp
index 58673269d..ff447488d 100644
--- a/test/functional/parser/ParseMdpTest.cpp
+++ b/test/functional/parser/ParseMdpTest.cpp
@@ -11,7 +11,7 @@
 #include "src/parser/NondeterministicModelParser.h"
 
 TEST(ParseMdpTest, parseAndOutput) {
-	storm::models::Mdp<double> mdp = storm::parser::NondeterministicModelParserAsMdp(
+	storm::models::Mdp<double> mdp = storm::parser::NondeterministicModelParser::parseMdp(
 		STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input_01.tra",
 		STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
 	storm::storage::SparseMatrix<double> const& matrix = mdp.getTransitionMatrix();

From 46e783c981236e3d3019c123c2269da68dfe9682 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Tue, 14 Jan 2014 01:48:04 +0100
Subject: [PATCH 010/147] Refactored AtomicPropositionLabelingParser.

- Not much to do here.
- Mostly comment corrections and code restructuring.

Next up: Parser.h/.cpp and the AutoParser.


Former-commit-id: 22d67dadb86c7ea0da1b1b53973a5c5fcaef0124
---
 .../AtomicPropositionLabelingParser.cpp       | 295 ++++++++----------
 src/parser/AtomicPropositionLabelingParser.h  |  31 +-
 src/parser/DeterministicModelParser.cpp       |   2 +-
 .../DeterministicSparseTransitionParser.h     |   6 +-
 src/parser/MarkovAutomatonParser.cpp          |   2 +-
 src/parser/NondeterministicModelParser.cpp    |   2 +-
 test/functional/parser/ReadLabFileTest.cpp    |  10 +-
 7 files changed, 162 insertions(+), 186 deletions(-)

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index 427d64ba9..c0a058381 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -6,193 +6,164 @@
  */
 
 #include "src/parser/AtomicPropositionLabelingParser.h"
+#include "src/parser/Parser.h"
 
-#include <errno.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <locale.h>
-
-#include <cstdlib>
-#include <cstdio>
 #include <cstring>
 #include <string>
-#include <clocale>
 #include <iostream>
 
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
-#include "src/utility/OsDetection.h"
 
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;
 
 namespace storm {
-namespace parser {
+	namespace parser {
 
+		storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const & filename) {
 
-/*!
- *	Reads a label file and puts the result in a labeling structure.
- *
- *	Labelings created with this method have to be freed with the delete operator.
- *	@param node_count the number of states.
- *	@param filename   input .lab file's name.
- *	@return The pointer to the created labeling object.
- */
-storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser(uint_fast64_t node_count, std::string const & filename) {
-	/*
-	 *	Open file.
-	 */
-	if (!storm::parser::fileExistsAndIsReadable(filename.c_str())) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-		throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process.";
-	}
-
-	/*
-	 *	Find out about the used line endings.
-	 */
-	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
-
-	MappedFile file(filename.c_str());
-	char* buf = file.data;
-
-	/*
-	 *	First run: obtain number of propositions.
-	 */
-	char separator[5];// = " \r\n\t";
-	storm::parser::getMatchingSeparatorString(separator, sizeof(separator), lineEndings);
-
-	bool foundDecl = false, foundEnd = false;
-	uint_fast32_t proposition_count = 0;
-	{
-		size_t cnt = 0;
-		/*
-		 *	Iterate over tokens until we hit #END or end of file.
-		 */
-		while(buf[0] != '\0') {
-			buf += cnt;
-			cnt = strcspn(buf, separator);  // position of next separator
-			if (cnt > 0) {
-				/*
-				 *	next token is #DECLARATION: just skip it
-				 *	next token is #END: stop search
-				 *	otherwise increase proposition_count
-				 */
-				if (strncmp(buf, "#DECLARATION", cnt) == 0) {
-					foundDecl = true;
-					continue;
-				} else if (strncmp(buf, "#END", cnt) == 0) {
-					foundEnd = true;
-					break;
+			// Open the given file.
+			if (!storm::parser::fileExistsAndIsReadable(filename.c_str())) {
+				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+				throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process.";
+			}
+
+			// Find out about the used line endings.
+			SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+
+			MappedFile file(filename.c_str());
+			char* buf = file.data;
+
+			// First pass: Count the number of propositions.
+			// Convert the line endings into a string containing all whitespace characters, that separate words in the file.
+			char separator[5];
+			storm::parser::getMatchingSeparatorString(separator, sizeof(separator), lineEndings);
+
+			bool foundDecl = false, foundEnd = false;
+			uint_fast32_t proposition_count = 0;
+			size_t cnt = 0;
+
+			// Iterate over tokens until we hit #END or the end of the file.
+			while(buf[0] != '\0') {
+
+				// Move the buffer pointer to the separator.
+				buf += cnt;
+
+				// Get the number of characters until the next separator.
+				cnt = strcspn(buf, separator);
+				if (cnt > 0) {
+
+					// If the next token is #DECLARATION: Just skip it.
+					// If the next token is #END: Stop the search.
+					// Otherwise increase proposition_count.
+					if (strncmp(buf, "#DECLARATION", cnt) == 0) {
+						foundDecl = true;
+						continue;
+					} else if (strncmp(buf, "#END", cnt) == 0) {
+						foundEnd = true;
+						break;
+					}
+					proposition_count++;
+				} else {
+
+					// If the next character is a separator, skip it.
+					buf++;
 				}
-				proposition_count++;
-			} else {
-				buf++;  // next char is separator, one step forward
 			}
-		}
 
-		/*
-		 *	If #DECLARATION or #END were not found, the file format is wrong
-		 */
-		if (!(foundDecl && foundEnd)) {
-			LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). File header is corrupted.");
-			if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
-			if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
-			throw storm::exceptions::WrongFormatException();
-		}
-	}
-
-	/*
-	 *	create labeling object with given node and proposition count
-	 */
-	storm::models::AtomicPropositionsLabeling labeling(node_count, proposition_count);
-
-	/*
-	 *	second run: add propositions and node labels to labeling
-	 *
-	 *	first thing to do: reset file pointer
-	 */	
-	buf = file.data;
-	{
-		/*
-		 *	load propositions
-		 *	As we already checked the file format, we can be a bit sloppy here...
-		 */
-		char proposition[128];  // buffer for proposition names
-		size_t cnt = 0;
-		do {
-			buf += cnt;
-			cnt = strcspn(buf, separator);  // position of next separator
-			if (cnt >= sizeof(proposition)) {
-				/*
-				 *	if token is longer than our buffer, the following strncpy code might get risky...
-				 */
-				LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition with length > " << (sizeof(proposition)-1) << " was found.");
+			// If #DECLARATION or #END have not been found, the file format is wrong.
+			if (!(foundDecl && foundEnd)) {
+				LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). File header is corrupted.");
+				if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
+				if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
 				throw storm::exceptions::WrongFormatException();
-			} else if (cnt > 0) {
-				/*
-				 *	next token is: #DECLARATION: just skip it
-				 *	next token is: #END: stop search
-				 *	otherwise: copy token to buffer, append trailing null byte and hand it to labeling
-				 */
-				if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
-				if (strncmp(buf, "#END", cnt) == 0) break;
-				strncpy(proposition, buf, cnt);
-				proposition[cnt] = '\0';
-				labeling.addAtomicProposition(proposition);
-			} else {
-				cnt = 1;  // next char is separator, one step forward
 			}
-		} while (cnt > 0);
-		/*
-		 *	Right here, the buf pointer is still pointing to our last token,
-		 *	i.e. to #END. We want to skip this one...
-		 */
-		buf += 4;
-	}
-
-	{
-		/*
-		 *	now parse node label assignments
-		 */
-		uint_fast64_t node;
-		char proposition[128];
-		size_t cnt;
-		/*
-		 *	iterate over nodes
-		 */
-		while (buf[0] != '\0') {
-			/*
-			 *	parse node number, then iterate over propositions
-			 */
-			node = checked_strtol(buf, &buf);
-			while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
+
+
+			// Create labeling object with given node and proposition count.
+			storm::models::AtomicPropositionsLabeling labeling(node_count, proposition_count);
+
+			// Second pass: Add propositions and node labels to labeling.
+			// First thing to do: Reset the file pointer.
+			buf = file.data;
+
+			// Prepare a buffer for proposition names.
+			char proposition[128];
+			cnt = 0;
+
+			// Parse proposition names.
+			// As we already checked the file header, we know that #DECLARATION and #END are tokens in the character stream.
+			while(buf[0] != '\0') {
+
+				// Move the buffer pointer to the separator.
+				buf += cnt;
+
+				// The number of characters until the next separator.
 				cnt = strcspn(buf, separator);
-				if (cnt == 0) {
-					/*
-					 *	next char is a separator
-					 *	if it's a newline, we continue with next node
-					 *	otherwise we skip it and try again
-					 */
-					if (buf[0] == '\n' || buf[0] == '\r') break;
-					buf++;
-				} else {
-					/*
-					 *	copy proposition to buffer and add it to labeling
-					 */
+
+				if (cnt >= sizeof(proposition)) {
+
+					// if token is longer than our buffer, the following strncpy code might get risky...
+					LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition with length > " << (sizeof(proposition)-1) << " was found.");
+					throw storm::exceptions::WrongFormatException();
+
+				} else if (cnt > 0) {
+
+					// If the next token is #DECLARATION: Just skip it.
+					if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
+
+					// If the next token is #END: Stop the search.
+					if (strncmp(buf, "#END", cnt) == 0) break;
+
+					// Otherwise copy the token to the buffer, append a trailing null byte and hand it to labeling.
 					strncpy(proposition, buf, cnt);
 					proposition[cnt] = '\0';
-					labeling.addAtomicPropositionToState(proposition, node);
-					buf += cnt;
+					labeling.addAtomicProposition(proposition);
+				} else {
+
+					// The next character is a separator, thus move one step forward.
+					buf++;
 				}
 			}
-			buf = storm::parser::trimWhitespaces(buf);
+
+			// At this point, the pointer buf is still pointing to our last token, i.e. to #END.
+			// We want to skip it.
+			buf += 4;
+
+			uint_fast64_t node;
+			cnt = 0;
+
+			// Now parse the assignments of labels to nodes.
+			while (buf[0] != '\0') {
+
+				// Parse the node number and iterate over its labels (atomic propositions).
+				// Stop at the end of the line.
+				node = checked_strtol(buf, &buf);
+				while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
+					cnt = strcspn(buf, separator);
+					if (cnt == 0) {
+
+						// The next character is a separator.
+						// If it is a line separator, we continue with next node.
+						// Otherwise, we skip it and try again.
+						if (buf[0] == '\n' || buf[0] == '\r') break;
+						buf++;
+					} else {
+
+						// Copy the label to the buffer, null terminate it and add it to labeling.
+						strncpy(proposition, buf, cnt);
+						proposition[cnt] = '\0';
+						labeling.addAtomicPropositionToState(proposition, node);
+						buf += cnt;
+					}
+				}
+				buf = trimWhitespaces(buf);
+			}
+
+			return labeling;
 		}
-	}
-    
-	return labeling;
-}
 
-}  // namespace parser
+	}  // namespace parser
 }  // namespace storm
diff --git a/src/parser/AtomicPropositionLabelingParser.h b/src/parser/AtomicPropositionLabelingParser.h
index 578b1d9ae..976dd9f35 100644
--- a/src/parser/AtomicPropositionLabelingParser.h
+++ b/src/parser/AtomicPropositionLabelingParser.h
@@ -1,23 +1,28 @@
-#ifndef STORM_PARSER_LABPARSER_H_
-#define STORM_PARSER_LABPARSER_H_
+#ifndef STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_
+#define STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_
 
 #include "src/models/AtomicPropositionsLabeling.h"
 #include <cstdint>
 
-#include "src/parser/Parser.h"
+namespace storm {
+	namespace parser {
 
-#include <memory>
+		class AtomicPropositionLabelingParser {
 
-namespace storm {
-namespace parser {
+		public:
+
+			/*
+			 *	Reads a label file and puts the result in an AtomicPropositionsLabeling object.
+			 *
+			 *	@param node_count The number of states of the model to be labeled.
+			 *	@param filename The path and name of the labeling (.lab) file.
+			 *	@return The parsed labeling as an AtomicPropositionsLabeling object.
+			 */
+			static storm::models::AtomicPropositionsLabeling parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const &filename);
 
-/*!
- *	@brief Load label file and return initialized AtomicPropositionsLabeling object.
- *
- */
-storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser(uint_fast64_t node_count, std::string const &filename);
+		};
 
-} // namespace parser
+	} // namespace parser
 } // namespace storm
 
-#endif /* STORM_PARSER_LABPARSER_H_ */
+#endif /* STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_ */
diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index 3f25b9c0c..ca841396a 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -33,7 +33,7 @@ DeterministicModelParser::Result DeterministicModelParser::parseDeterministicMod
 	uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
 	uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
 
-	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
+	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
 
 	DeterministicModelParser::Result result(std::move(resultTransitionSystem), std::move(labeling));
 
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index b9bb1621e..004210aa1 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -1,5 +1,5 @@
-#ifndef STORM_PARSER_TRAPARSER_H_
-#define STORM_PARSER_TRAPARSER_H_
+#ifndef STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
+#define STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
 
 #include "src/storage/SparseMatrix.h"
 #include "src/parser/Parser.h"
@@ -82,4 +82,4 @@ private:
 
 } // namespace storm
 
-#endif /* STORM_PARSER_TRAPARSER_H_ */
+#endif /* STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_ */
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index cf98ded11..172d71ecd 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -16,7 +16,7 @@ storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomat
 	storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0));
 
 	// Parse the state labeling.
-	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionMatrix.getColumnCount(), labelingFilename));
+	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename));
 
 	// If given, parse the state rewards file.
 	boost::optional<std::vector<double>> stateRewards;
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index fd2e85912..528f62f51 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -35,7 +35,7 @@ namespace storm {
 			uint_fast64_t stateCount = transitions.getColumnCount();
 			uint_fast64_t rowCount = transitions.getRowCount();
 
-			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
+			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
 
 			Result result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling));
 
diff --git a/test/functional/parser/ReadLabFileTest.cpp b/test/functional/parser/ReadLabFileTest.cpp
index 2e35ee1ae..8c0a31b89 100644
--- a/test/functional/parser/ReadLabFileTest.cpp
+++ b/test/functional/parser/ReadLabFileTest.cpp
@@ -16,14 +16,14 @@
 
 TEST(ReadLabFileTest, NonExistingFileTest) {
    // No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
 }
 
 TEST(ReadLabFileTest, ParseTest) {
 	// This test is based on a test case from the original MRMC.
 	
 	// Parsing the file
-	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
+	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
 
 	// Checking whether all propositions are in the labelling
 
@@ -79,14 +79,14 @@ TEST(ReadLabFileTest, ParseTest) {
 }
 
 TEST(ReadLabFileTest, WrongHeaderTest1) {
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException);
+   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException);
 }
 
 TEST(ReadLabFileTest, WrongHeaderTest2) {
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException);
+   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException);
 }
 
 TEST(ReadLabFileTest, WrongPropositionTest) {
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException);
+   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException);
 }
 

From 15d13bc06d86a50b43e5ab7b5991d9c3011cf708 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Tue, 21 Jan 2014 00:58:29 +0100
Subject: [PATCH 011/147] Refactored the AutoParser.

- Devided the AutoParser.h into .h and .cpp
- The AutoParser now is a stateless class
|- This resulted in changes to the interface between the parsers and the rest of the project.
|- The main() now directly acquires a shared_ptr to an AbstractModel from the call of the AutoParser and keeps ownership of it.
|- Additionally, the division into .h and .cpp lead to a move of includes from the header to the source. This caused several tests to need some model header to be included.
|- Tests are still showing green (except those needing Gurobi, which I do not have).

Next up: Parser.h/.cpp, then comments and making things look nice.)


Former-commit-id: f59b7405e5dda9971064bb36ba023ca3aef9dd86
---
 .../PathBasedSubsystemGenerator.h             |   2 +-
 src/parser/AutoParser.cpp                     |  94 ++++++++++
 src/parser/AutoParser.h                       | 163 ++++--------------
 src/storm.cpp                                 |  47 ++---
 .../GmmxxDtmcPrctlModelCheckerTest.cpp        |  18 +-
 .../SparseMdpPrctlModelCheckerTest.cpp        |  24 +--
 .../MaximalEndComponentDecompositionTest.cpp  |  15 +-
 ...glyConnectedComponentDecompositionTest.cpp |  11 +-
 test/performance/graph/GraphTest.cpp          |  20 ++-
 .../GmmxxDtmcPrctModelCheckerTest.cpp         |  14 +-
 .../SparseMdpPrctlModelCheckerTest.cpp        |  14 +-
 .../MaximalEndComponentDecompositionTest.cpp  |  11 +-
 ...glyConnectedComponentDecompositionTest.cpp |  20 ++-
 13 files changed, 234 insertions(+), 219 deletions(-)
 create mode 100644 src/parser/AutoParser.cpp

diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h
index 58678a390..11e24d00d 100644
--- a/src/counterexamples/PathBasedSubsystemGenerator.h
+++ b/src/counterexamples/PathBasedSubsystemGenerator.h
@@ -507,7 +507,7 @@ public:
 	/*!
 	 *
 	 */
-	static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T>& model, storm::property::prctl::AbstractStateFormula<T> const& stateFormula) {
+	static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> & model, storm::property::prctl::AbstractStateFormula<T> const& stateFormula) {
 
 		//-------------------------------------------------------------
 		// 1. Strip and handle formulas
diff --git a/src/parser/AutoParser.cpp b/src/parser/AutoParser.cpp
new file mode 100644
index 000000000..ba9ec8323
--- /dev/null
+++ b/src/parser/AutoParser.cpp
@@ -0,0 +1,94 @@
+/*
+ * AutoParser.cpp
+ *
+ *  Created on: Jan 20, 2014
+ *      Author: Manuel S. Weiand
+ */
+
+#include "src/parser/AutoParser.h"
+
+#include "src/parser/Parser.h"
+
+#include "src/parser/DeterministicModelParser.h"
+#include "src/parser/NondeterministicModelParser.h"
+#include "src/parser/MarkovAutomatonParser.h"
+#include "src/exceptions/WrongFormatException.h"
+
+namespace storm {
+	namespace parser {
+
+		std::shared_ptr<storm::models::AbstractModel<double>> AutoParser::parseModel(std::string const & transitionSystemFile,
+																					 std::string const & labelingFile,
+																					 std::string const & stateRewardFile,
+																					 std::string const & transitionRewardFile) {
+
+			// Find and parse the model type hint.
+			storm::models::ModelType type = AutoParser::analyzeHint(transitionSystemFile);
+
+			// In case the hint string is unknown or could not be found, throw an exception.
+			if (type == storm::models::Unknown) {
+				LOG4CPLUS_ERROR(logger, "Could not determine file type of " << transitionSystemFile << ".");
+				LOG4CPLUS_ERROR(logger, "The first line of the file should contain a format hint. Please fix your file and try again.");
+				throw storm::exceptions::WrongFormatException() << "Could not determine type of file " << transitionSystemFile;
+			} else {
+				LOG4CPLUS_INFO(logger, "Model type seems to be " << type);
+			}
+
+			// Do the actual parsing.
+			std::shared_ptr<storm::models::AbstractModel<double>> model;
+			switch (type) {
+				case storm::models::DTMC: {
+					model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParser::parseDtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					break;
+				}
+				case storm::models::CTMC: {
+					model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParser::parseCtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					break;
+				}
+				case storm::models::MDP: {
+					model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParser::parseMdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					break;
+				}
+				case storm::models::CTMDP: {
+					model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParser::parseCtmdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					break;
+				}
+				case storm::models::MA: {
+					model.reset(new storm::models::MarkovAutomaton<double>(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
+					break;
+				}
+				default:
+					LOG4CPLUS_WARN(logger, "Unknown/Unhandled Model Type which cannot be parsed.");  // Unknown
+			}
+
+			return model;
+		}
+
+		storm::models::ModelType AutoParser::analyzeHint(const std::string& filename) {
+			storm::models::ModelType hintType = storm::models::Unknown;
+
+			// Find out the line endings used within the file.
+			storm::parser::SupportedLineEndingsEnum lineEndings = storm::parser::findUsedLineEndings(filename);
+
+			// Open the file.
+			MappedFile file(filename.c_str());
+			char* buf = file.data;
+
+			// Find and read in the hint.
+			char hint[128];
+			// %20s => The input hint can be AT MOST 120 chars long.
+			storm::parser::scanForModelHint(hint, sizeof(hint), buf, lineEndings);
+
+			for (char* c = hint; *c != '\0'; c++) *c = toupper(*c);
+
+			// Check if the hint value is known and store the appropriate enum value.
+			if (strncmp(hint, "DTMC", sizeof(hint)) == 0) hintType = storm::models::DTMC;
+			else if (strncmp(hint, "CTMC", sizeof(hint)) == 0) hintType = storm::models::CTMC;
+			else if (strncmp(hint, "MDP", sizeof(hint)) == 0) hintType = storm::models::MDP;
+			else if (strncmp(hint, "CTMDP", sizeof(hint)) == 0) hintType = storm::models::CTMDP;
+			else if (strncmp(hint, "MA", sizeof(hint)) == 0) hintType = storm::models::MA;
+
+			return hintType;
+		}
+	}
+}
diff --git a/src/parser/AutoParser.h b/src/parser/AutoParser.h
index 59082a135..d09897922 100644
--- a/src/parser/AutoParser.h
+++ b/src/parser/AutoParser.h
@@ -1,140 +1,49 @@
 #ifndef STORM_PARSER_AUTOPARSER_H_
 #define STORM_PARSER_AUTOPARSER_H_
 
-#include "src/parser/Parser.h"
 #include "src/models/AbstractModel.h"
 
-#include "src/exceptions/WrongFormatException.h"
-#include "src/models/AbstractModel.h"
-#include "src/parser/DeterministicModelParser.h"
-#include "src/parser/NondeterministicModelParser.h"
-#include "src/parser/MarkovAutomatonParser.h"
-
-#include <memory>
-#include <iostream>
-#include <utility>
 #include <string>
-#include <cctype>
 
 namespace storm {
-
-namespace parser {
-
-/*!
- *	@brief Checks the given files and parses the model within these files.
- *
- *	This parser analyzes the format hint in the first line of the transition
- *	file. If this is a valid format, it will use the parser for this format,
- *	otherwise it will throw an exception.
- *
- *	When the files are parsed successfully, the parsed ModelType and Model
- *	can be obtained via getType() and getModel<ModelClass>().
- */
-template<class T>
-class AutoParser {
-	public:
-		AutoParser(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "") : model(nullptr) {
-			storm::models::ModelType type = this->analyzeHint(transitionSystemFile);
-
-			if (type == storm::models::Unknown) {
-				LOG4CPLUS_ERROR(logger, "Could not determine file type of " << transitionSystemFile << ".");
-				LOG4CPLUS_ERROR(logger, "The first line of the file should contain a format hint. Please fix your file and try again.");
-				throw storm::exceptions::WrongFormatException() << "Could not determine type of file " << transitionSystemFile;
-			} else {
-				LOG4CPLUS_INFO(logger, "Model type seems to be " << type);
-			}
-
-			// Do actual parsing
-			switch (type) {
-				case storm::models::DTMC: {
-					this->model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParser::parseDtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
-					break;
-				}
-				case storm::models::CTMC: {
-					this->model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParser::parseCtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
-					break;
-				}
-				case storm::models::MDP: {
-					this->model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParser::parseMdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
-					break;
-				}
-				case storm::models::CTMDP: {
-					this->model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParser::parseCtmdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
-					break;
-				}
-                case storm::models::MA: {
-                    this->model.reset(new storm::models::MarkovAutomaton<double>(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
-					break;
-                }
-				default: ;  // Unknown
-			}
-
-
-			if (!this->model) {
-				LOG4CPLUS_WARN(logger, "Unknown/Unhandled Model Type. Model is still null.");
-			}
-		}
+	namespace parser {
+
+		class AutoParser {
+			public:
+
+				/*!
+				 *	Checks the given files and parses the model within these files.
+				 *
+				 *	This parser analyzes the format hint in the first line of the transition
+				 *	file. If this is a valid format, it will use the parser for this format,
+				 *	otherwise it will throw an exception.
+				 *
+				 *	When the files are parsed successfully, a shared pointer owning the resulting model is returned.
+				 *	The concrete model can be obtained using the as<Type>() member of the AbstractModel class.
+				 *
+				 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
+				 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
+				 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
+				 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
+				 * @return A shared_ptr containing the resulting model.
+				 */
+				static std::shared_ptr<storm::models::AbstractModel<double>> parseModel(std::string const & transitionSystemFile,
+																	   std::string const & labelingFile,
+																	   std::string const & stateRewardFile = "",
+																	   std::string const & transitionRewardFile = "");
 		
-		/*!
-		 *	@brief 	Returns the type of model that was parsed.
-		 */
-		storm::models::ModelType getType() {
-			if (this->model) {
-				return this->model->getType();
-			} else {
-				return storm::models::Unknown;
-			}
-		}
+			private:
+
+				/*!
+				 *	Opens the given file and parses the file format hint.
+				 *
+				 *	@param filename The path and name of the file that is to be analysed.
+				 *	@return The type of the model as an enum value.
+				 */
+				static storm::models::ModelType analyzeHint(const std::string& filename);
+		};
 		
-		/*!
-		 *	@brief	Returns the model with the given type.
-		 */
-		template <typename Model>
-		std::shared_ptr<Model> getModel() {
-			return this->model->template as<Model>();
-		}
-
-	private:
-		
-		/*!
-		 *	@brief	Open file and read file format hint.
-		 */
-		storm::models::ModelType analyzeHint(const std::string& filename) {
-			storm::models::ModelType hintType = storm::models::Unknown;
-			
-			// Parse the File and check for the Line Endings
-			storm::parser::SupportedLineEndingsEnum lineEndings = storm::parser::findUsedLineEndings(filename);
-			
-			// Open file
-			MappedFile file(filename.c_str());
-			char* buf = file.data;
-
-			// parse hint
-			char hint[128];
-			// %20s => The Input Hint can be AT MOST 120 chars long			
-			storm::parser::scanForModelHint(hint, sizeof(hint), buf, lineEndings);
-
-			for (char* c = hint; *c != '\0'; c++) *c = toupper(*c);
-
-			// check hint
-			if (strncmp(hint, "DTMC", sizeof(hint)) == 0) hintType = storm::models::DTMC;
-			else if (strncmp(hint, "CTMC", sizeof(hint)) == 0) hintType = storm::models::CTMC;
-			else if (strncmp(hint, "MDP", sizeof(hint)) == 0) hintType = storm::models::MDP;
-			else if (strncmp(hint, "CTMDP", sizeof(hint)) == 0) hintType = storm::models::CTMDP;
-            else if (strncmp(hint, "MA", sizeof(hint)) == 0) hintType = storm::models::MA;
-
-			return hintType;
-		}
-		
-		/*!
-		 *	@brief	Pointer to a parser that has parsed the given transition system.
-		 */
-		std::shared_ptr<storm::models::AbstractModel<T>> model;
-};
-
-} // namespace parser
-
+	} // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_AUTOPARSER_H_ */
diff --git a/src/storm.cpp b/src/storm.cpp
index 88ecafad4..cef1c793e 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -210,7 +210,7 @@ void cleanUp() {
  * @param dtmc A reference to the DTMC for which the model checker is to be created.
  * @return A pointer to the resulting model checker.
  */
-storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Dtmc<double>& dtmc) {
+storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Dtmc<double> const & dtmc) {
     // Create the appropriate model checker.
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
 	std::string const chosenMatrixLibrary = s->getOptionByLongName("matrixLibrary").getArgument(0).getValueAsString();
@@ -230,7 +230,7 @@ storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecke
  * @param mdp The Dtmc that the model checker will check
  * @return
  */
-storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Mdp<double>& mdp) {
+storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Mdp<double> const & mdp) {
     // Create the appropriate model checker.
     return new storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double>(mdp);
 }
@@ -259,13 +259,13 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double>
  *
  * @param parser An AutoParser to get the model from.
  */
- void generateCounterExample(storm::parser::AutoParser<double> parser) {
+ void generateCounterExample(std::shared_ptr<storm::models::AbstractModel<double>> model) {
 	LOG4CPLUS_INFO(logger, "Starting counterexample generation.");
 	LOG4CPLUS_INFO(logger, "Testing inputs...");
 
 	storm::settings::Settings* s  = storm::settings::Settings::getInstance();
 
-	//First test output directory.
+	// First test output directory.
 	std::string outPath = s->getOptionByLongName("counterExample").getArgument(0).getValueAsString();
 	if(outPath.back() != '/' && outPath.back() != '\\') {
 		LOG4CPLUS_ERROR(logger, "The output path is not valid.");
@@ -279,13 +279,16 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double>
 	testFile.close();
 	std::remove((outPath + "test.dot").c_str());
 
- 	//Differentiate between model types.
-	if(parser.getType() != storm::models::DTMC) {
+ 	// Differentiate between model types.
+	if(model->getType() != storm::models::DTMC) {
 		LOG4CPLUS_ERROR(logger, "Counterexample generation for the selected model type is not supported.");
 		return;
 	}
 
-	storm::models::Dtmc<double> model = *parser.getModel<storm::models::Dtmc<double>>();
+	// Get the Dtmc back from the AbstractModel
+	// Note that the ownership of the object referenced by dtmc lies at the main function.
+	// Thus, it must not be deleted.
+	storm::models::Dtmc<double> dtmc = *(model->as<storm::models::Dtmc<double>>());
 	LOG4CPLUS_INFO(logger, "Model is a DTMC.");
 
 	// Get specified PRCTL formulas.
@@ -346,10 +349,10 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double>
 		// Also raise the logger threshold for the log file, so that the model check infos aren't logged (useless and there are lots of them)
 		// Lower it again after the model check.
 		logger.getAppender("mainFileAppender")->setThreshold(log4cplus::WARN_LOG_LEVEL);
-		storm::storage::BitVector result = stateForm.check(*createPrctlModelChecker(model));
+		storm::storage::BitVector result = stateForm.check(*createPrctlModelChecker(dtmc));
 		logger.getAppender("mainFileAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL);
 
-		if((result & model.getInitialStates()).getNumberOfSetBits() == model.getInitialStates().getNumberOfSetBits()) {
+		if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) {
 			std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl;
 			LOG4CPLUS_INFO(logger, "Formula is satisfied. Can not generate counterexample.");
 			delete formula;
@@ -357,7 +360,7 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double>
 		}
 
 		// Generate counterexample
-		storm::models::Dtmc<double> counterExample = storm::counterexamples::PathBasedSubsystemGenerator<double>::computeCriticalSubsystem(*parser.getModel<storm::models::Dtmc<double>>(), stateForm);
+		storm::models::Dtmc<double> counterExample = storm::counterexamples::PathBasedSubsystemGenerator<double>::computeCriticalSubsystem(dtmc, stateForm);
 
 		LOG4CPLUS_INFO(logger, "Found counterexample.");
 
@@ -418,19 +421,19 @@ int main(const int argc, const char* argv[]) {
 				chosenTransitionRewardsFile = s->getOptionByLongName("transitionRewards").getArgument(0).getValueAsString();
 			}
 
-			storm::parser::AutoParser<double> parser(chosenTransitionSystemFile, chosenLabelingFile, chosenStateRewardsFile, chosenTransitionRewardsFile);
+			std::shared_ptr<storm::models::AbstractModel<double>> model = storm::parser::AutoParser::parseModel(chosenTransitionSystemFile, chosenLabelingFile, chosenStateRewardsFile, chosenTransitionRewardsFile);
 
             if (s->isSet("exportdot")) {
                 std::ofstream outputFileStream;
                 outputFileStream.open(s->getOptionByLongName("exportdot").getArgument(0).getValueAsString(), std::ofstream::out);
-                parser.getModel<storm::models::AbstractModel<double>>()->writeDotToStream(outputFileStream);
+                model->writeDotToStream(outputFileStream);
                 outputFileStream.close();
             }
             
 			//Should there be a counterexample generated in case the formula is not satisfied?
 			if(s->isSet("counterexample")) {
 
-				generateCounterExample(parser);
+				generateCounterExample(model);
 			
 			} else {
 				// Determine which engine is to be used to choose the right model checker.
@@ -438,17 +441,17 @@ int main(const int argc, const char* argv[]) {
 
 				// Depending on the model type, the appropriate model checking procedure is chosen.
 				storm::modelchecker::prctl::AbstractModelChecker<double>* modelchecker = nullptr;
-				parser.getModel<storm::models::AbstractModel<double>>()->printModelInformationToStream(std::cout);
+				model->printModelInformationToStream(std::cout);
                 
-				switch (parser.getType()) {
+				switch (model->getType()) {
 				case storm::models::DTMC:
 					LOG4CPLUS_INFO(logger, "Model is a DTMC.");
-					modelchecker = createPrctlModelChecker(*parser.getModel<storm::models::Dtmc<double>>());
+					modelchecker = createPrctlModelChecker(*model->as<storm::models::Dtmc<double>>());
 					checkPrctlFormulae(*modelchecker);
 					break;
 				case storm::models::MDP:
 					LOG4CPLUS_INFO(logger, "Model is an MDP.");
-					modelchecker = createPrctlModelChecker(*parser.getModel<storm::models::Mdp<double>>());
+					modelchecker = createPrctlModelChecker(*model->as<storm::models::Mdp<double>>());
 					checkPrctlFormulae(*modelchecker);
 					break;
 				case storm::models::CTMC:
@@ -461,13 +464,13 @@ int main(const int argc, const char* argv[]) {
 					break;
                 case storm::models::MA: {
                     LOG4CPLUS_INFO(logger, "Model is a Markov automaton.");
-                    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = parser.getModel<storm::models::MarkovAutomaton<double>>();
-                    markovAutomaton->close();
-                    storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(*markovAutomaton);
+                    storm::models::MarkovAutomaton<double> markovAutomaton = *model->as<storm::models::MarkovAutomaton<double>>();
+                    markovAutomaton.close();
+                    storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(markovAutomaton);
 //                    std::cout << mc.checkExpectedTime(true, markovAutomaton->getLabeledStates("goal")) << std::endl;
 //                    std::cout << mc.checkExpectedTime(false, markovAutomaton->getLabeledStates("goal")) << std::endl;
-                    std::cout << mc.checkLongRunAverage(true, markovAutomaton->getLabeledStates("goal")) << std::endl;
-                    std::cout << mc.checkLongRunAverage(false, markovAutomaton->getLabeledStates("goal")) << std::endl;
+                    std::cout << mc.checkLongRunAverage(true, markovAutomaton.getLabeledStates("goal")) << std::endl;
+                    std::cout << mc.checkLongRunAverage(false, markovAutomaton.getLabeledStates("goal")) << std::endl;
 //                    std::cout << mc.checkTimeBoundedEventually(true, markovAutomaton->getLabeledStates("goal"), 0, 1) << std::endl;
 //                    std::cout << mc.checkTimeBoundedEventually(true, markovAutomaton->getLabeledStates("goal"), 1, 2) << std::endl;
                     break;
diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
index d724ef23d..fdff14a66 100644
--- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
+++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
@@ -11,11 +11,11 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
 	storm::settings::InternalOptionMemento deadlockOption("fixDeadlocks", true);
 	ASSERT_TRUE(s->isSet("fixDeadlocks"));
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
 
-	ASSERT_EQ(parser.getType(), storm::models::DTMC);
+	ASSERT_EQ(abstractModel->getType(), storm::models::DTMC);
 
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 13ull);
 	ASSERT_EQ(dtmc->getNumberOfTransitions(), 27ull);
@@ -67,11 +67,11 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
 	storm::settings::InternalOptionMemento deadlockOption("fixDeadlocks", true);
 	ASSERT_TRUE(s->isSet("fixDeadlocks"));
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", "");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.lab", "", "");
 
-	ASSERT_EQ(parser.getType(), storm::models::DTMC);
+	ASSERT_EQ(abstractModel->getType(), storm::models::DTMC);
 
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 8607ull);
 	ASSERT_EQ(dtmc->getNumberOfTransitions(), 22460ull);
@@ -113,10 +113,10 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
 	storm::settings::InternalOptionMemento deadlockOption("fixDeadlocks", true);
 	ASSERT_TRUE(s->isSet("fixDeadlocks"));
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader4_8.pick.trans.rew");
 
-	ASSERT_EQ(parser.getType(), storm::models::DTMC);
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	ASSERT_EQ(abstractModel->getType(), storm::models::DTMC);
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 12400ull);
 	ASSERT_EQ(dtmc->getNumberOfTransitions(), 28894ull);
diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp
index 83b4afdb2..67fe2d63a 100644
--- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp
+++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp
@@ -8,11 +8,11 @@
 
 TEST(SparseMdpPrctlModelCheckerTest, Dice) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew");
     
-	ASSERT_EQ(parser.getType(), storm::models::MDP);
+	ASSERT_EQ(abstractModel->getType(), storm::models::MDP);
     
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
     
 	ASSERT_EQ(mdp->getNumberOfStates(), 169ull);
 	ASSERT_EQ(mdp->getNumberOfTransitions(), 436ull);
@@ -97,11 +97,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) {
 	ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
 	delete rewardFormula;
     
-	storm::parser::AutoParser<double> stateRewardParser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", "");
+	abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", "");
     
-	ASSERT_EQ(stateRewardParser.getType(), storm::models::MDP);
+	ASSERT_EQ(abstractModel->getType(), storm::models::MDP);
     
-	std::shared_ptr<storm::models::Mdp<double>> stateRewardMdp = stateRewardParser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::Mdp<double>> stateRewardMdp = abstractModel->as<storm::models::Mdp<double>>();
     
     storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateRewardModelChecker(*stateRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>()));
 
@@ -123,11 +123,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) {
 	ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
 	delete rewardFormula;
     
-	storm::parser::AutoParser<double> stateAndTransitionRewardParser(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew");
+	abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew");
     
-	ASSERT_EQ(stateAndTransitionRewardParser.getType(), storm::models::MDP);
+	ASSERT_EQ(abstractModel->getType(), storm::models::MDP);
     
-	std::shared_ptr<storm::models::Mdp<double>> stateAndTransitionRewardMdp = stateAndTransitionRewardParser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::Mdp<double>> stateAndTransitionRewardMdp = abstractModel->as<storm::models::Mdp<double>>();
     
 	storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>()));
     
@@ -152,11 +152,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) {
 
 TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew");
 
-	ASSERT_EQ(parser.getType(), storm::models::MDP);
+	ASSERT_EQ(abstractModel->getType(), storm::models::MDP);
 
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
 
 	ASSERT_EQ(mdp->getNumberOfStates(), 3172ull);
 	ASSERT_EQ(mdp->getNumberOfTransitions(), 7144ull);
diff --git a/test/functional/storage/MaximalEndComponentDecompositionTest.cpp b/test/functional/storage/MaximalEndComponentDecompositionTest.cpp
index cacb33843..1a6112148 100644
--- a/test/functional/storage/MaximalEndComponentDecompositionTest.cpp
+++ b/test/functional/storage/MaximalEndComponentDecompositionTest.cpp
@@ -2,11 +2,12 @@
 #include "storm-config.h"
 #include "src/parser/AutoParser.h"
 #include "src/storage/MaximalEndComponentDecomposition.h"
+#include "src/models/MarkovAutomaton.h"
 
 TEST(MaximalEndComponentDecomposition, FullSystem1) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.lab", "", "");
+    std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.lab", "", "");
 
-    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = parser.getModel<storm::models::MarkovAutomaton<double>>();
+    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = abstractModel->as<storm::models::MarkovAutomaton<double>>();
 
     storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition;
     ASSERT_NO_THROW(mecDecomposition = storm::storage::MaximalEndComponentDecomposition<double>(*markovAutomaton));
@@ -72,9 +73,9 @@ TEST(MaximalEndComponentDecomposition, FullSystem1) {
 }
 
 TEST(MaximalEndComponentDecomposition, FullSystem2) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.lab", "", "");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.lab", "", "");
     
-    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = parser.getModel<storm::models::MarkovAutomaton<double>>();
+    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = abstractModel->as<storm::models::MarkovAutomaton<double>>();
     
     storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition;
     ASSERT_NO_THROW(mecDecomposition = storm::storage::MaximalEndComponentDecomposition<double>(*markovAutomaton));
@@ -101,9 +102,9 @@ TEST(MaximalEndComponentDecomposition, FullSystem2) {
 }
 
 TEST(MaximalEndComponentDecomposition, Subsystem) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.lab", "", "");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.lab", "", "");
     
-    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = parser.getModel<storm::models::MarkovAutomaton<double>>();
+    std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = abstractModel->as<storm::models::MarkovAutomaton<double>>();
     
     storm::storage::BitVector subsystem(markovAutomaton->getNumberOfStates(), true);
     subsystem.set(7, false);
@@ -130,4 +131,4 @@ TEST(MaximalEndComponentDecomposition, Subsystem) {
         // This case must never happen as the only two existing MEC contains 3.
         ASSERT_TRUE(false);
     }
-}
\ No newline at end of file
+}
diff --git a/test/functional/storage/StronglyConnectedComponentDecompositionTest.cpp b/test/functional/storage/StronglyConnectedComponentDecompositionTest.cpp
index 22f04d0d1..21939d1bf 100644
--- a/test/functional/storage/StronglyConnectedComponentDecompositionTest.cpp
+++ b/test/functional/storage/StronglyConnectedComponentDecompositionTest.cpp
@@ -2,10 +2,12 @@
 #include "storm-config.h"
 #include "src/parser/AutoParser.h"
 #include "src/storage/StronglyConnectedComponentDecomposition.h"
+#include "src/models/MarkovAutomaton.h"
 
 TEST(StronglyConnectedComponentDecomposition, FullSystem1) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.lab", "", "");
-	std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = parser.getModel<storm::models::MarkovAutomaton<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny1.lab", "", "");
+
+	std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = abstractModel->as<storm::models::MarkovAutomaton<double>>();
     
     storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition;
 
@@ -22,8 +24,9 @@ TEST(StronglyConnectedComponentDecomposition, FullSystem1) {
 }
 
 TEST(StronglyConnectedComponentDecomposition, FullSystem2) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.lab", "", "");
-	std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = parser.getModel<storm::models::MarkovAutomaton<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.tra", STORM_CPP_BASE_PATH "/examples/ma/tiny/tiny2.lab", "", "");
+
+	std::shared_ptr<storm::models::MarkovAutomaton<double>> markovAutomaton = abstractModel->as<storm::models::MarkovAutomaton<double>>();
     
     storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition;
     ASSERT_NO_THROW(sccDecomposition = storm::storage::StronglyConnectedComponentDecomposition<double>(*markovAutomaton, true, false));
diff --git a/test/performance/graph/GraphTest.cpp b/test/performance/graph/GraphTest.cpp
index b3355c398..e0fe1b9b4 100644
--- a/test/performance/graph/GraphTest.cpp
+++ b/test/performance/graph/GraphTest.cpp
@@ -4,11 +4,13 @@
 #include "src/parser/AutoParser.h"
 #include "src/utility/graph.h"
 #include "src/storage/StronglyConnectedComponentDecomposition.h"
+#include "src/models/Mdp.h"
+#include "src/models/Dtmc.h"
 
 TEST(GraphTest, PerformProb01) {
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
 
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 	storm::storage::BitVector trueStates(dtmc->getNumberOfStates(), true);
 
     LOG4CPLUS_WARN(logger, "Computing prob01 (3 times) for crowds/crowds20_5...");
@@ -31,9 +33,9 @@ TEST(GraphTest, PerformProb01) {
     
     dtmc = nullptr;
     
-    storm::parser::AutoParser<double> parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", "");
+    abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", "");
     
-    std::shared_ptr<storm::models::Dtmc<double>> dtmc2 = parser2.getModel<storm::models::Dtmc<double>>();
+    std::shared_ptr<storm::models::Dtmc<double>> dtmc2 = abstractModel->as<storm::models::Dtmc<double>>();
     trueStates = storm::storage::BitVector(dtmc2->getNumberOfStates(), true);
 
     LOG4CPLUS_WARN(logger, "Computing prob01 for synchronous_leader/leader6_8...");
@@ -47,8 +49,8 @@ TEST(GraphTest, PerformProb01) {
 }
 
 TEST(GraphTest, PerformProb01MinMax) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", "");
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", "");
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
 	storm::storage::BitVector trueStates(mdp->getNumberOfStates(), true);
     
     LOG4CPLUS_WARN(logger, "Computing prob01min for asynchronous_leader/leader7...");
@@ -67,8 +69,8 @@ TEST(GraphTest, PerformProb01MinMax) {
     
     mdp = nullptr;
 
-    storm::parser::AutoParser<double> parser2(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", "", "");
-	std::shared_ptr<storm::models::Mdp<double>> mdp2 = parser2.getModel<storm::models::Mdp<double>>();
+    abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", "", "");
+	std::shared_ptr<storm::models::Mdp<double>> mdp2 = abstractModel->as<storm::models::Mdp<double>>();
 	trueStates = storm::storage::BitVector(mdp2->getNumberOfStates(), true);
 
     LOG4CPLUS_WARN(logger, "Computing prob01min for consensus/coin4_6...");
@@ -86,4 +88,4 @@ TEST(GraphTest, PerformProb01MinMax) {
     ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616ull);
     
     mdp2 = nullptr;
-}
\ No newline at end of file
+}
diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
index c9c309d60..809f602fb 100644
--- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
+++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
@@ -10,11 +10,11 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
 	storm::settings::InternalOptionMemento deadlockOption("fixDeadlocks", true);
 	ASSERT_TRUE(s->isSet("fixDeadlocks"));
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
 
-	ASSERT_EQ(parser.getType(), storm::models::DTMC);
+	ASSERT_EQ(abstractModel->getType(), storm::models::DTMC);
 
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 2036647ull);
 	ASSERT_EQ(dtmc->getNumberOfTransitions(), 8973900ull);
@@ -63,12 +63,12 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
 	storm::settings::InternalOptionMemento deadlockOption("fixDeadlocks", true);
 	ASSERT_TRUE(s->isSet("fixDeadlocks"));
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew");
 
-	ASSERT_EQ(parser.getType(), storm::models::DTMC);
+	ASSERT_EQ(abstractModel->getType(), storm::models::DTMC);
 
 
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 1312334ull);
 	ASSERT_EQ(dtmc->getNumberOfTransitions(), 2886810ull);
@@ -110,4 +110,4 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
 	ASSERT_LT(std::abs(result[0] - 1.025106273), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
 
 	delete rewardFormula;
-}
\ No newline at end of file
+}
diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp
index 4a8193d26..8f083f89f 100644
--- a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp
+++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp
@@ -8,11 +8,11 @@
 
 TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) {
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew");
 
-	ASSERT_EQ(parser.getType(), storm::models::MDP);
+	ASSERT_EQ(abstractModel->getType(), storm::models::MDP);
 
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
 
 	ASSERT_EQ(mdp->getNumberOfStates(), 2095783ull);
 	ASSERT_EQ(mdp->getNumberOfTransitions(), 7714385ull);
@@ -79,11 +79,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) {
     // Increase the maximal number of iterations, because the solver does not converge otherwise.
 	// This is done in the main cpp unit
     
-	storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", "");
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", "");
     
-	ASSERT_EQ(parser.getType(), storm::models::MDP);
+	ASSERT_EQ(abstractModel->getType(), storm::models::MDP);
     
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
     
 	ASSERT_EQ(mdp->getNumberOfStates(), 63616ull);
 	ASSERT_EQ(mdp->getNumberOfTransitions(), 213472ull);
@@ -168,4 +168,4 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) {
     
 	ASSERT_LT(std::abs(result[31168] - 2183.142422), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
 	delete rewardFormula;
-}
\ No newline at end of file
+}
diff --git a/test/performance/storage/MaximalEndComponentDecompositionTest.cpp b/test/performance/storage/MaximalEndComponentDecompositionTest.cpp
index a34a35091..ee5460fed 100644
--- a/test/performance/storage/MaximalEndComponentDecompositionTest.cpp
+++ b/test/performance/storage/MaximalEndComponentDecompositionTest.cpp
@@ -2,10 +2,11 @@
 #include "storm-config.h"
 #include "src/parser/AutoParser.h"
 #include "src/storage/MaximalEndComponentDecomposition.h"
+#include "src/models/Mdp.h"
 
 TEST(MaximalEndComponentDecomposition, AsynchronousLeader) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", "");
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", "");
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
     
     storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition;
     ASSERT_NO_THROW(mecDecomposition = storm::storage::MaximalEndComponentDecomposition<double>(*mdp));
@@ -15,12 +16,12 @@ TEST(MaximalEndComponentDecomposition, AsynchronousLeader) {
 }
 
 TEST(MaximalEndComponentDecomposition, Consensus) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.lab", "", "");
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.lab", "", "");
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
     
     storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition;
     ASSERT_NO_THROW(mecDecomposition = storm::storage::MaximalEndComponentDecomposition<double>(*mdp));
     
     ASSERT_EQ(384, mecDecomposition.size());
     mdp = nullptr;
-}
\ No newline at end of file
+}
diff --git a/test/performance/storage/StronglyConnectedComponentDecompositionTest.cpp b/test/performance/storage/StronglyConnectedComponentDecompositionTest.cpp
index b519c27be..83bc77de6 100644
--- a/test/performance/storage/StronglyConnectedComponentDecompositionTest.cpp
+++ b/test/performance/storage/StronglyConnectedComponentDecompositionTest.cpp
@@ -2,10 +2,12 @@
 #include "storm-config.h"
 #include "src/parser/AutoParser.h"
 #include "src/storage/StronglyConnectedComponentDecomposition.h"
+#include "src/models/Mdp.h"
+#include "src/models/Dtmc.h"
 
 TEST(StronglyConnectedComponentDecomposition, Crowds) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
-	std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
+	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
     
     storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition;
 
@@ -22,8 +24,8 @@ TEST(StronglyConnectedComponentDecomposition, Crowds) {
 }
 
 TEST(StronglyConnectedComponentDecomposition, SynchronousLeader) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_9.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_9.lab", "", "");
-    std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_9.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_9.lab", "", "");
+    std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
     
     storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition;
 
@@ -40,8 +42,8 @@ TEST(StronglyConnectedComponentDecomposition, SynchronousLeader) {
 }
 
 TEST(StronglyConnectedComponentDecomposition, AsynchronousLeader) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", "");
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", "");
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
     
     storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition;
     
@@ -58,8 +60,8 @@ TEST(StronglyConnectedComponentDecomposition, AsynchronousLeader) {
 }
 
 TEST(StronglyConnectedComponentDecomposition, Consensus) {
-    storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.lab", "", "");
-	std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
+	std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin6_4.lab", "", "");
+	std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>();
     
     storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition;
     
@@ -73,4 +75,4 @@ TEST(StronglyConnectedComponentDecomposition, Consensus) {
     ASSERT_EQ(384, sccDecomposition.size());
 
     mdp = nullptr;
-}
\ No newline at end of file
+}

From 538f911283064ae1f4205b16ee54c4e12c3822bf Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 22 Jan 2014 18:10:23 +0100
Subject: [PATCH 012/147] First part of the refactoring of Parser.h/.cpp

- Removed the RewardMatrixInformationStruct since it was only used as function argument.
|- Replaced its function by the respective results of the transition parser (for det/non-det)
- Moved the MappedFile class to separate file.
- Renamed the SupportedFileEndingsEnum enum to SupportedFileEndings.
- Whats left in Parser.*:
|- A bunch of free functions for manipulation of c-style strings, a function to read the model hint and the SupportedFileEndings enum with its recognition function.

Im not exactly sure what to do with this.
- I think the name Parser.* implies a parser base class, while it is not. Therefore: Renaming.
- The c-style string manipulation functions might also needed elsewhere. Therefore: Moving them into the utility folder/namespace.
- The model hint function would fit in the AutoParser, except for its signature (low level arguments vs. high level arguments of the AutoParser). Therefore: Either moving it to the Auto Parser or leave it as helper function with the others (c-style string handling and low level OS detection)
- The SupportedLineEndings and its assorted functions either belong to the string manipulation functions or to the MappedFile class. Therefor: Moving them accordingly.
- Once all things have moved the Parser.* will be empty. Therefore: Deletion.

Next up: Trying to decide what to do with the rest of the Parser.* and doing it.


Former-commit-id: aa7417e5e1beed5d83fc7c348e42c13319a4ea0d
---
 .../AtomicPropositionLabelingParser.cpp       |   5 +-
 src/parser/AutoParser.cpp                     |   7 +-
 src/parser/AutoParser.h                       |  64 ++--
 src/parser/DeterministicModelParser.cpp       |  19 +-
 .../DeterministicSparseTransitionParser.cpp   | 360 +++++++++---------
 .../DeterministicSparseTransitionParser.h     |  14 +-
 src/parser/MappedFile.cpp                     | 101 +++++
 src/parser/MappedFile.h                       |  95 +++++
 .../MarkovAutomatonSparseTransitionParser.cpp |   7 +-
 .../MarkovAutomatonSparseTransitionParser.h   |   4 +-
 src/parser/NondeterministicModelParser.cpp    |  27 +-
 ...NondeterministicSparseTransitionParser.cpp | 241 ++++++------
 .../NondeterministicSparseTransitionParser.h  |  26 +-
 src/parser/Parser.cpp                         | 132 ++-----
 src/parser/Parser.h                           | 199 +++-------
 src/parser/SparseStateRewardParser.cpp        |   1 +
 16 files changed, 679 insertions(+), 623 deletions(-)
 create mode 100644 src/parser/MappedFile.cpp
 create mode 100644 src/parser/MappedFile.h

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index c0a058381..aaca0d7a3 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -6,12 +6,13 @@
  */
 
 #include "src/parser/AtomicPropositionLabelingParser.h"
-#include "src/parser/Parser.h"
 
 #include <cstring>
 #include <string>
 #include <iostream>
 
+#include "src/parser/Parser.h"
+#include "src/parser/MappedFile.h"
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
 
@@ -31,7 +32,7 @@ namespace storm {
 			}
 
 			// Find out about the used line endings.
-			SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+			SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
 
 			MappedFile file(filename.c_str());
 			char* buf = file.data;
diff --git a/src/parser/AutoParser.cpp b/src/parser/AutoParser.cpp
index ba9ec8323..91e28c9d2 100644
--- a/src/parser/AutoParser.cpp
+++ b/src/parser/AutoParser.cpp
@@ -8,6 +8,7 @@
 #include "src/parser/AutoParser.h"
 
 #include "src/parser/Parser.h"
+#include "src/parser/MappedFile.h"
 
 #include "src/parser/DeterministicModelParser.h"
 #include "src/parser/NondeterministicModelParser.h"
@@ -68,7 +69,7 @@ namespace storm {
 			storm::models::ModelType hintType = storm::models::Unknown;
 
 			// Find out the line endings used within the file.
-			storm::parser::SupportedLineEndingsEnum lineEndings = storm::parser::findUsedLineEndings(filename);
+			storm::parser::SupportedLineEndings lineEndings = storm::parser::findUsedLineEndings(filename);
 
 			// Open the file.
 			MappedFile file(filename.c_str());
@@ -90,5 +91,5 @@ namespace storm {
 
 			return hintType;
 		}
-	}
-}
+	} // namespace parser
+} // namespace storm
diff --git a/src/parser/AutoParser.h b/src/parser/AutoParser.h
index d09897922..2e52fad59 100644
--- a/src/parser/AutoParser.h
+++ b/src/parser/AutoParser.h
@@ -9,38 +9,38 @@ namespace storm {
 	namespace parser {
 
 		class AutoParser {
-			public:
-
-				/*!
-				 *	Checks the given files and parses the model within these files.
-				 *
-				 *	This parser analyzes the format hint in the first line of the transition
-				 *	file. If this is a valid format, it will use the parser for this format,
-				 *	otherwise it will throw an exception.
-				 *
-				 *	When the files are parsed successfully, a shared pointer owning the resulting model is returned.
-				 *	The concrete model can be obtained using the as<Type>() member of the AbstractModel class.
-				 *
-				 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
-				 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
-				 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
-				 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
-				 * @return A shared_ptr containing the resulting model.
-				 */
-				static std::shared_ptr<storm::models::AbstractModel<double>> parseModel(std::string const & transitionSystemFile,
-																	   std::string const & labelingFile,
-																	   std::string const & stateRewardFile = "",
-																	   std::string const & transitionRewardFile = "");
-		
-			private:
-
-				/*!
-				 *	Opens the given file and parses the file format hint.
-				 *
-				 *	@param filename The path and name of the file that is to be analysed.
-				 *	@return The type of the model as an enum value.
-				 */
-				static storm::models::ModelType analyzeHint(const std::string& filename);
+		public:
+
+			/*!
+			 *	Checks the given files and parses the model within these files.
+			 *
+			 *	This parser analyzes the format hint in the first line of the transition
+			 *	file. If this is a valid format, it will use the parser for this format,
+			 *	otherwise it will throw an exception.
+			 *
+			 *	When the files are parsed successfully, a shared pointer owning the resulting model is returned.
+			 *	The concrete model can be obtained using the as<Type>() member of the AbstractModel class.
+			 *
+			 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
+			 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
+			 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
+			 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
+			 * @return A shared_ptr containing the resulting model.
+			 */
+			static std::shared_ptr<storm::models::AbstractModel<double>> parseModel(std::string const & transitionSystemFile,
+																   std::string const & labelingFile,
+																   std::string const & stateRewardFile = "",
+																   std::string const & transitionRewardFile = "");
+
+		private:
+
+			/*!
+			 *	Opens the given file and parses the file format hint.
+			 *
+			 *	@param filename The path and name of the file that is to be analysed.
+			 *	@return The type of the model as an enum value.
+			 */
+			static storm::models::ModelType analyzeHint(const std::string& filename);
 		};
 		
 	} // namespace parser
diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index ca841396a..48b613644 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -28,24 +28,25 @@ namespace parser {
  */
 DeterministicModelParser::Result DeterministicModelParser::parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-	storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionSystemFile)));
+	// Parse the transitions.
+	storm::storage::SparseMatrix<double> transitions(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionSystemFile)));
 
-	uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
-	uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
+	uint_fast64_t stateCount = transitions.getColumnCount();
 
+	// Parse the state labeling.
 	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
 
-	DeterministicModelParser::Result result(std::move(resultTransitionSystem), std::move(labeling));
+	// Construct the result.
+	DeterministicModelParser::Result result(std::move(transitions), std::move(labeling));
 
-	// Only parse state rewards of a file is given.
+	// Only parse state rewards if a file is given.
 	if (stateRewardFile != "") {
-		result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
+		result.stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile);
 	}
 
-	// Only parse transition rewards of a file is given.
+	// Only parse transition rewards if a file is given.
 	if (transitionRewardFile != "") {
-		RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, nullptr);
-		result.transitionRewards.reset(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo)));
+		result.transitionRewards = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFile, result.transitionSystem);
 	}
 
 	return result;
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 2ac9098bd..666a45039 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -15,7 +15,7 @@
 #include <string>
 
 #include "src/utility/constants.h"
-
+#include "src/parser/MappedFile.h"
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
 #include "src/settings/Settings.h"
@@ -25,241 +25,239 @@
 extern log4cplus::Logger logger;
 
 namespace storm {
+	namespace parser {
 
-namespace parser {
+		storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename) {
 
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing) {
+			storm::storage::SparseMatrix<double> emptyMatrix;
 
-	RewardMatrixInformationStruct nullInformation;
+			return DeterministicSparseTransitionParser::parse(filename, false, emptyMatrix);
+		}
 
-	return DeterministicSparseTransitionParser::parse(filename, false, nullInformation, insertDiagonalEntriesIfMissing);
-}
+		storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & transitionMatrix) {
 
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+			return DeterministicSparseTransitionParser::parse(filename, true, transitionMatrix);
+		}
 
-	return DeterministicSparseTransitionParser::parse(filename, true, rewardMatrixInformation);
-}
+		storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & transitionMatrix) {
+			// Enforce locale where decimal point is '.'.
+				setlocale(LC_NUMERIC, "C");
 
-DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing) {
+				if (!fileExistsAndIsReadable(filename.c_str())) {
+					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+					throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
+				}
 
-	DeterministicSparseTransitionParser::FirstPassResult result;
+				// Find out about the used line endings.
+				SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
 
-	// Skip the format hint if it is there.
-	buf = trimWhitespaces(buf);
-	if(buf[0] < '0' || buf[0] > '9') {
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
-	}
+				// Open file.
+				MappedFile file(filename.c_str());
+				char* buf = file.data;
 
-	 // Check all transitions for non-zero diagonal entries and deadlock states.
-	uint_fast64_t row, col, lastRow = 0;
-	bool rowHadDiagonalEntry = false;
-	while (buf[0] != '\0') {
+				// Perform first pass, i.e. count entries that are not zero.
+				bool insertDiagonalEntriesIfMissing = !isRewardFile;
+				DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, insertDiagonalEntriesIfMissing);
 
-		// Read the transition.
-		row = checked_strtol(buf, &buf);
-		col = checked_strtol(buf, &buf);
-		// The actual read value is not needed here.
-		checked_strtod(buf, &buf);
+				LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
 
-		// Compensate for missing diagonal entries if desired.
-		if (insertDiagonalEntriesIfMissing) {
-			if (lastRow != row) {
-				if(!rowHadDiagonalEntry) {
-					++result.numberOfNonzeroEntries;
+				// If first pass returned zero, the file format was wrong.
+				if (firstPass.numberOfNonzeroEntries == 0) {
+					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
+					throw storm::exceptions::WrongFormatException();
 				}
 
-				// Compensate for missing rows.
-				for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
-					++result.numberOfNonzeroEntries;
+				// Perform second pass.
+
+				// Skip the format hint if it is there.
+				buf = trimWhitespaces(buf);
+				if(buf[0] < '0' || buf[0] > '9') {
+					buf = storm::parser::forwardToNextLine(buf, lineEndings);
 				}
-				lastRow = row;
-				rowHadDiagonalEntry = false;
-			}
 
-			if (col == row) {
-				rowHadDiagonalEntry = true;
-			}
+				if(isRewardFile) {
+					// The reward matrix should match the size of the transition matrix.
+					if (firstPass.highestStateIndex + 1 > transitionMatrix.getRowCount() || firstPass.highestStateIndex + 1 > transitionMatrix.getColumnCount()) {
+						LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
+						throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
+					} else {
+						// If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
+						firstPass.highestStateIndex = transitionMatrix.getRowCount() - 1;
+					}
+				}
 
-			if (col > row && !rowHadDiagonalEntry) {
-				rowHadDiagonalEntry = true;
-				++result.numberOfNonzeroEntries;
-			}
-		}
+				// Creating matrix builder here.
+				// The actual matrix will be build once all contents are inserted.
+				storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
 
-		// Check if a higher state id was found.
-		if (row > result.highestStateIndex) result.highestStateIndex = row;
-		if (col > result.highestStateIndex) result.highestStateIndex = col;
+				uint_fast64_t row, col, lastRow = 0;
+				double val;
+				bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+				bool hadDeadlocks = false;
+				bool rowHadDiagonalEntry = false;
 
-		++result.numberOfNonzeroEntries;
-		buf = trimWhitespaces(buf);
-	}
 
-	if(insertDiagonalEntriesIfMissing) {
-		if (!rowHadDiagonalEntry) {
-			++result.numberOfNonzeroEntries;
-		}
+				// Read all transitions from file. Note that we assume that the
+				// transitions are listed in canonical order, otherwise this will not
+				// work, i.e. the values in the matrix will be at wrong places.
 
-		//Compensate for missing rows at the end of the file.
-		for (uint_fast64_t skippedRow = (uint_fast64_t)(lastRow + 1); skippedRow <= result.highestStateIndex; ++skippedRow) {
-			++result.numberOfNonzeroEntries;
-		}
-	}
+				// Different parsing routines for transition systems and transition rewards.
+				if(isRewardFile) {
+					while (buf[0] != '\0') {
 
-	return result;
-}
+						// Read next transition.
+						row = checked_strtol(buf, &buf);
+						col = checked_strtol(buf, &buf);
+						val = checked_strtod(buf, &buf);
 
-storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(std::string const& filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation, bool insertDiagonalEntriesIfMissing) {
-	// Enforce locale where decimal point is '.'.
-		setlocale(LC_NUMERIC, "C");
+						resultMatrix.addNextValue(row, col, val);
+						buf = trimWhitespaces(buf);
+					}
+				} else {
+					while (buf[0] != '\0') {
+
+						// Read next transition.
+						row = checked_strtol(buf, &buf);
+						col = checked_strtol(buf, &buf);
+						val = checked_strtod(buf, &buf);
+
+						// Read probability of this transition.
+						// Check, if the value is a probability, i.e. if it is between 0 and 1.
+						if ((val < 0.0) || (val > 1.0)) {
+							LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
+							throw storm::exceptions::WrongFormatException();
+						}
 
-		if (!fileExistsAndIsReadable(filename.c_str())) {
-			LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-			throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
-		}
+						// Test if we moved to a new row.
+						// Handle all incomplete or skipped rows.
+						if (lastRow != row) {
+							if (!rowHadDiagonalEntry) {
+								if (insertDiagonalEntriesIfMissing) {
+									resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
+									LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
+								} else {
+									LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+								}
+								// No increment for lastRow.
+								rowHadDiagonalEntry = true;
+							}
+							for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
+								hadDeadlocks = true;
+								if (fixDeadlocks) {
+									resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
+									rowHadDiagonalEntry = true;
+									LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
+								} else {
+									LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
+									// Before throwing the appropriate exception we will give notice of all deadlock states.
+								}
+							}
+							lastRow = row;
+							rowHadDiagonalEntry = false;
+						}
 
-		// Find out about the used line endings.
-		SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+						if (col == row) {
+							rowHadDiagonalEntry = true;
+						}
 
-		// Open file.
-		MappedFile file(filename.c_str());
-		char* buf = file.data;
+						if (col > row && !rowHadDiagonalEntry) {
+							if (insertDiagonalEntriesIfMissing) {
+								resultMatrix.addNextValue(row, row, storm::utility::constantZero<double>());
+								LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
+							} else {
+								LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
+							}
+							rowHadDiagonalEntry = true;
+						}
 
-		// Perform first pass, i.e. count entries that are not zero.
+						resultMatrix.addNextValue(row, col, val);
+						buf = trimWhitespaces(buf);
+					}
 
-		DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, insertDiagonalEntriesIfMissing);
+					if (!rowHadDiagonalEntry) {
+						if (insertDiagonalEntriesIfMissing) {
+							resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
+							LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
+						} else {
+							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+						}
+					}
 
-		LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
+					// If we encountered deadlock and did not fix them, now is the time to throw the exception.
+					if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
+				}
 
-		// If first pass returned zero, the file format was wrong.
-		if (firstPass.numberOfNonzeroEntries == 0) {
-			LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
-			throw storm::exceptions::WrongFormatException();
+				// Finally, build the actual matrix and return it.
+				return resultMatrix.build();
 		}
 
-		// Perform second pass.
+		DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndings lineEndings, bool insertDiagonalEntriesIfMissing) {
 
-		// Skip the format hint if it is there.
-		buf = trimWhitespaces(buf);
-		if(buf[0] < '0' || buf[0] > '9') {
-			buf = storm::parser::forwardToNextLine(buf, lineEndings);
-		}
+			DeterministicSparseTransitionParser::FirstPassResult result;
 
-		if(isRewardFile) {
-			// The reward matrix should match the size of the transition matrix.
-			if (firstPass.highestStateIndex + 1 > rewardMatrixInformation.rowCount || firstPass.highestStateIndex + 1 > rewardMatrixInformation.columnCount) {
-				LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
-				throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
-			} else {
-				// If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
-				firstPass.highestStateIndex = rewardMatrixInformation.rowCount - 1;
+			// Skip the format hint if it is there.
+			buf = trimWhitespaces(buf);
+			if(buf[0] < '0' || buf[0] > '9') {
+				buf = storm::parser::forwardToNextLine(buf, lineEndings);
 			}
-		}
-
-		// Creating matrix builder here.
-		// The actual matrix will be build once all contents are inserted.
-		storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
 
-		uint_fast64_t row, col, lastRow = 0;
-		double val;
-		bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-		bool hadDeadlocks = false;
-		bool rowHadDiagonalEntry = false;
-
-
-		// Read all transitions from file. Note that we assume that the
-		// transitions are listed in canonical order, otherwise this will not
-		// work, i.e. the values in the matrix will be at wrong places.
-
-		// Different parsing routines for transition systems and transition rewards.
-		if(isRewardFile) {
-			while (buf[0] != '\0') {
-
-				// Read next transition.
-				row = checked_strtol(buf, &buf);
-				col = checked_strtol(buf, &buf);
-				val = checked_strtod(buf, &buf);
-
-				resultMatrix.addNextValue(row, col, val);
-				buf = trimWhitespaces(buf);
-			}
-		} else {
+			 // Check all transitions for non-zero diagonal entries and deadlock states.
+			uint_fast64_t row, col, lastRow = 0;
+			bool rowHadDiagonalEntry = false;
 			while (buf[0] != '\0') {
 
-				// Read next transition.
+				// Read the transition.
 				row = checked_strtol(buf, &buf);
 				col = checked_strtol(buf, &buf);
-				val = checked_strtod(buf, &buf);
+				// The actual read value is not needed here.
+				checked_strtod(buf, &buf);
 
-				// Read probability of this transition.
-				// Check, if the value is a probability, i.e. if it is between 0 and 1.
-				if ((val < 0.0) || (val > 1.0)) {
-					LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
-					throw storm::exceptions::WrongFormatException();
-				}
-
-				// Test if we moved to a new row.
-				// Handle all incomplete or skipped rows.
-				if (lastRow != row) {
-					if (!rowHadDiagonalEntry) {
-						if (insertDiagonalEntriesIfMissing) {
-							resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
-							LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
-						} else {
-							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+				// Compensate for missing diagonal entries if desired.
+				if (insertDiagonalEntriesIfMissing) {
+					if (lastRow != row) {
+						if(!rowHadDiagonalEntry) {
+							++result.numberOfNonzeroEntries;
 						}
-						// No increment for lastRow.
-						rowHadDiagonalEntry = true;
-					}
-					for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
-						hadDeadlocks = true;
-						if (fixDeadlocks) {
-							resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
-							rowHadDiagonalEntry = true;
-							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
-						} else {
-							LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
-							// Before throwing the appropriate exception we will give notice of all deadlock states.
+
+						// Compensate for missing rows.
+						for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
+							++result.numberOfNonzeroEntries;
 						}
+						lastRow = row;
+						rowHadDiagonalEntry = false;
 					}
-					lastRow = row;
-					rowHadDiagonalEntry = false;
-				}
 
-				if (col == row) {
-					rowHadDiagonalEntry = true;
-				}
+					if (col == row) {
+						rowHadDiagonalEntry = true;
+					}
 
-				if (col > row && !rowHadDiagonalEntry) {
-					if (insertDiagonalEntriesIfMissing) {
-						resultMatrix.addNextValue(row, row, storm::utility::constantZero<double>());
-						LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
-					} else {
-						LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
+					if (col > row && !rowHadDiagonalEntry) {
+						rowHadDiagonalEntry = true;
+						++result.numberOfNonzeroEntries;
 					}
-					rowHadDiagonalEntry = true;
 				}
 
-				resultMatrix.addNextValue(row, col, val);
+				// Check if a higher state id was found.
+				if (row > result.highestStateIndex) result.highestStateIndex = row;
+				if (col > result.highestStateIndex) result.highestStateIndex = col;
+
+				++result.numberOfNonzeroEntries;
 				buf = trimWhitespaces(buf);
 			}
 
-			if (!rowHadDiagonalEntry) {
-				if (insertDiagonalEntriesIfMissing) {
-					resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
-					LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
-				} else {
-					LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+			if(insertDiagonalEntriesIfMissing) {
+				if (!rowHadDiagonalEntry) {
+					++result.numberOfNonzeroEntries;
+				}
+
+				//Compensate for missing rows at the end of the file.
+				for (uint_fast64_t skippedRow = (uint_fast64_t)(lastRow + 1); skippedRow <= result.highestStateIndex; ++skippedRow) {
+					++result.numberOfNonzeroEntries;
 				}
 			}
 
-			// If we encountered deadlock and did not fix them, now is the time to throw the exception.
-			if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
+			return result;
 		}
 
-		// Finally, build the actual matrix and return it.
-		return resultMatrix.build();
-}
-
-}  // namespace parser
-
+	}  // namespace parser
 }  // namespace storm
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index 004210aa1..a9147f763 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -34,7 +34,7 @@ public:
 	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 	 * @return A SparseMatrix containing the parsed transition system.
 	 */
-	static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename, bool insertDiagonalEntriesIfMissing = true);
+	static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename);
 
 	/*!
 	 * Load the transition rewards for a deterministic transition system from file and create a
@@ -46,10 +46,11 @@ public:
 	 * sparse adjacency matrix whose entries represent the rewards of the respective transitions.
 	 *
 	 * @param filename The path of file to be parsed.
-	 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
+	 * @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
+	 *                         The dimensions (rows and columns) of the two matrices should match.
 	 * @return A SparseMatrix containing the parsed transition rewards.
 	 */
-	static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation);
+	static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & transitionMatrix);
 
 private:
 
@@ -62,7 +63,7 @@ private:
 	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 	 * @return A structure representing the result of the first pass.
 	 */
-	static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings, bool insertDiagonalEntriesIfMissing = true);
+	static FirstPassResult firstPass(char* buffer, SupportedLineEndings lineEndings, bool insertDiagonalEntriesIfMissing = true);
 
 	/*
 	 * The main parsing routine.
@@ -71,10 +72,11 @@ private:
 	 * @param filename The path of file to be parsed.
 	 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
 	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
-	 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
+	 * @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
+	 *                         The dimensions (rows and columns) of the two matrices should match.
 	 * @return A SparseMatrix containing the parsed file contents.
 	 */
-	static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation, bool insertDiagonalEntriesIfMissing = false);
+	static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & transitionMatrix);
 
 };
 
diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp
new file mode 100644
index 000000000..69d9fd4a9
--- /dev/null
+++ b/src/parser/MappedFile.cpp
@@ -0,0 +1,101 @@
+/*
+ * MappedFile.cpp
+ *
+ *  Created on: Jan 21, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "src/parser/MappedFile.h"
+
+#include <fstream>
+#include <cstring>
+#include <fcntl.h>
+
+#include <iostream>
+#include <string>
+
+#include <boost/integer/integer_mask.hpp>
+
+#include "src/exceptions/FileIoException.h"
+
+#include "log4cplus/logger.h"
+#include "log4cplus/loggingmacros.h"
+extern log4cplus::Logger logger;
+
+namespace storm {
+	namespace parser {
+
+		MappedFile::MappedFile(const char* filename) {
+		#if defined LINUX || defined MACOSX
+			/*
+			 *	Do file mapping for reasonable systems.
+			 *	stat64(), open(), mmap()
+			 */
+		#ifdef MACOSX
+			if (stat(filename, &(this->st)) != 0) {
+		#else
+			if (stat64(filename, &(this->st)) != 0) {
+		#endif
+				LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): Probably, this file does not exist.");
+				throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist.";
+			}
+			this->file = open(filename, O_RDONLY);
+
+			if (this->file < 0) {
+				LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): Probably, we may not read this file.");
+				throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file.";
+			}
+
+			this->data = reinterpret_cast<char*>(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0));
+			if (this->data == reinterpret_cast<char*>(-1)) {
+				close(this->file);
+				LOG4CPLUS_ERROR(logger, "Error in mmap(" << filename << "): " << std::strerror(errno));
+				throw exceptions::FileIoException() << "MappedFile Error in mmap(): " << std::strerror(errno);
+			}
+			this->dataend = this->data + this->st.st_size;
+		#elif defined WINDOWS
+			/*
+			 *	Do file mapping for windows.
+			 *	_stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile()
+			 */
+			if (_stat64(filename, &(this->st)) != 0) {
+				LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist.");
+				throw exceptions::FileIoException("MappedFile Error in stat(): Probably, this file does not exist.");
+			}
+
+			this->file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+			if (this->file == INVALID_HANDLE_VALUE) {
+				LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << "): Probably, we may not read this file.");
+				throw exceptions::FileIoException("MappedFile Error in CreateFileA(): Probably, we may not read this file.");
+			}
+
+			this->mapping = CreateFileMappingA(this->file, NULL, PAGE_READONLY, (DWORD)(st.st_size >> 32), (DWORD)st.st_size, NULL);
+			if (this->mapping == NULL) {
+				CloseHandle(this->file);
+				LOG4CPLUS_ERROR(logger, "Error in CreateFileMappingA(" << filename << ").");
+				throw exceptions::FileIoException("MappedFile Error in CreateFileMappingA().");
+			}
+
+			this->data = static_cast<char*>(MapViewOfFile(this->mapping, FILE_MAP_READ, 0, 0, this->st.st_size));
+			if (this->data == NULL) {
+				CloseHandle(this->mapping);
+				CloseHandle(this->file);
+				LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ").");
+				throw exceptions::FileIoException("MappedFile Error in MapViewOfFile().");
+			}
+			this->dataend = this->data + this->st.st_size;
+		#endif
+		}
+
+		MappedFile::~MappedFile() {
+		#if defined LINUX || defined MACOSX
+			munmap(this->data, this->st.st_size);
+			close(this->file);
+		#elif defined WINDOWS
+			CloseHandle(this->mapping);
+			CloseHandle(this->file);
+		#endif
+		}
+	} // namespace parser
+} // namespace storm
+
diff --git a/src/parser/MappedFile.h b/src/parser/MappedFile.h
new file mode 100644
index 000000000..8b66b0fde
--- /dev/null
+++ b/src/parser/MappedFile.h
@@ -0,0 +1,95 @@
+/*
+ * MappedFile.h
+ *
+ *  Created on: Jan 21, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#ifndef STORM_PARSER_MAPPEDFILE_H_
+#define STORM_PARSER_MAPPEDFILE_H_
+
+#include <sys/stat.h>
+
+#include "src/utility/OsDetection.h"
+
+namespace storm {
+	namespace parser {
+		/*!
+		 *	@brief Opens a file and maps it to memory providing a char*
+		 *	containing the file content.
+		 *
+		 *	This class is a very simple interface to read files efficiently.
+		 *	The given file is opened and mapped to memory using mmap().
+		 *	The public member data is a pointer to the actual file content.
+		 *	Using this method, the kernel will take care of all buffering. This is
+		 *	most probably much more efficient than doing this manually.
+		 */
+
+		#if !defined LINUX && !defined MACOSX && !defined WINDOWS
+		#error Platform not supported
+		#endif
+
+		class MappedFile {
+
+		public:
+
+			/*!
+			 * Constructor of MappedFile.
+			 * Will stat the given file, open it and map it to memory.
+			 * If anything of this fails, an appropriate exception is raised
+			 * and a log entry is written.
+			 * @param filename file to be opened
+			 */
+			MappedFile(const char* filename);
+
+			/*!
+			 * Destructor of MappedFile.
+			 * Will unmap the data and close the file.
+			 */
+			~MappedFile();
+
+			/*!
+			 *	@brief pointer to actual file content.
+			 */
+			char* data;
+
+			/*!
+			 *	@brief pointer to end of file content.
+			 */
+			char* dataend;
+
+		private:
+
+		#if defined LINUX || defined MACOSX
+			/*!
+			 *	@brief file descriptor obtained by open().
+			 */
+			int file;
+		#elif defined WINDOWS
+				HANDLE file;
+				HANDLE mapping;
+		#endif
+
+		#if defined LINUX
+			/*!
+			 *	@brief stat information about the file.
+			 */
+			struct stat64 st;
+		#elif defined MACOSX
+			/*!
+			 *	@brief stat information about the file.
+			 */
+			struct stat st;
+		#elif defined WINDOWS
+			/*!
+			 *	@brief stat information about the file.
+			 */
+			struct __stat64 st;
+		#endif
+		};
+	} // namespace parser
+} // namespace storm
+
+
+
+#endif /* STORM_PARSER_MAPPEDFILE_H_ */
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 15a7c5809..de950aab8 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -2,12 +2,13 @@
 
 #include "src/settings/Settings.h"
 #include "src/exceptions/WrongFormatException.h"
+#include "MappedFile.h"
 
 namespace storm {
 
 namespace parser {
 
-MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings) {
+MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf, SupportedLineEndings lineEndings) {
 	MarkovAutomatonSparseTransitionParser::FirstPassResult result;
 
 	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
@@ -142,7 +143,7 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 	return result;
 }
 
-MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, SupportedLineEndingsEnum lineEndings, FirstPassResult const& firstPassResult) {
+MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, SupportedLineEndings lineEndings, FirstPassResult const& firstPassResult) {
 	ResultType result(firstPassResult);
 
 	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
@@ -252,7 +253,7 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 	}
 
 	// Determine used line endings.
-	SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+	SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
 
 	// Open file and prepare pointer to buffer.
 	MappedFile file(filename.c_str());
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index ef89371e0..25f9291dc 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -80,7 +80,7 @@ private:
 	 * @param lineEndings The line endings that are to be used while parsing.
 	 * @return A structure representing the result of the first pass.
 	 */
-	static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings);
+	static FirstPassResult firstPass(char* buffer, SupportedLineEndings lineEndings);
 
 	/*
 	 * Performs the second pass on the input pointed to by the given buffer with the information of the first pass.
@@ -90,7 +90,7 @@ private:
 	 * @param firstPassResult The result of the first pass performed on the same input.
 	 * @return A structure representing the result of the second pass.
 	 */
-	static ResultType secondPass(char* buffer, SupportedLineEndingsEnum lineEndings, FirstPassResult const& firstPassResult);
+	static ResultType secondPass(char* buffer, SupportedLineEndings lineEndings, FirstPassResult const& firstPassResult);
 };
 
 } // namespace parser
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index 528f62f51..82a7f3085 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -29,26 +29,31 @@ namespace storm {
 		NondeterministicModelParser::Result NondeterministicModelParser::parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
 				std::string const & stateRewardFile, std::string const & transitionRewardFile) {
 
-			NondeterministicSparseTransitionParser::Result transitionParserResult(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionSystemFile)));
-			storm::storage::SparseMatrix<double> transitions(std::move(transitionParserResult.transitionMatrix));
+			// Parse the transitions.
+			NondeterministicSparseTransitionParser::Result transitions(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionSystemFile)));
 
-			uint_fast64_t stateCount = transitions.getColumnCount();
-			uint_fast64_t rowCount = transitions.getRowCount();
+			uint_fast64_t stateCount = transitions.transitionMatrix.getColumnCount();
 
+			// Parse the state labeling.
 			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
 
-			Result result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling));
-
-			// Only parse state rewards of a file is given.
+			// Only parse state rewards if a file is given.
+			boost::optional<std::vector<double>> stateRewards;
 			if (stateRewardFile != "") {
-				result.stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile));
+				stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile);
 			}
 
-			// Only parse transition rewards of a file is given.
+			// Only parse transition rewards if a file is given.
+			boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
 			if (transitionRewardFile != "") {
-				RewardMatrixInformationStruct rewardMatrixInfo(rowCount, stateCount, &result.rowMapping);
-				result.transitionRewards.reset(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFile, rewardMatrixInfo).transitionMatrix);
+				transitionRewards = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFile, transitions).transitionMatrix;
 			}
+
+			// Construct the result.
+			Result result(std::move(transitions.transitionMatrix), std::move(transitions.rowMapping), std::move(labeling));
+			result.stateRewards = stateRewards;
+			result.transitionRewards = transitionRewards;
+
 			return result;
 		}
 
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index fa20585ec..3c7ebbaab 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include "src/parser/MappedFile.h"
 #include "src/settings/Settings.h"
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
@@ -22,125 +23,17 @@ namespace storm {
 
 		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitions(std::string const& filename) {
 
-			RewardMatrixInformationStruct nullInformation;
+			Result emptyResult;
 
-			return NondeterministicSparseTransitionParser::parse(filename, false, nullInformation);
+			return NondeterministicSparseTransitionParser::parse(filename, false, emptyResult);
 		}
 
-		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(std::string const& filename, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(std::string const& filename, Result const & modelInformation) {
 
-			return NondeterministicSparseTransitionParser::parse(filename, true, rewardMatrixInformation);
+			return NondeterministicSparseTransitionParser::parse(filename, true, modelInformation);
 		}
 
-		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndingsEnum lineEndings, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation) {
-
-			// Check file header and extract number of transitions.
-
-			// Skip the format hint if it is there.
-			buf = trimWhitespaces(buf);
-			if(buf[0] < '0' || buf[0] > '9') {
-				buf = storm::parser::forwardToNextLine(buf, lineEndings);
-			}
-
-			// Read all transitions.
-			uint_fast64_t source = 0, target = 0, choice = 0, lastchoice = 0, lastsource = 0;
-			double val = 0.0;
-			NondeterministicSparseTransitionParser::FirstPassResult result;
-
-			// Since the first line is already a new choice but is not covered below, that has to be covered here.
-			result.choices = 1;
-
-			while (buf[0] != '\0') {
-
-				// Read source state and choice.
-				source = checked_strtol(buf, &buf);
-
-				// Read the name of the nondeterministic choice.
-				choice = checked_strtol(buf, &buf);
-
-				// Check if we encountered a state index that is bigger than all previously seen.
-				if (source > result.highestStateIndex) {
-					result.highestStateIndex = source;
-				}
-
-				if (isRewardFile) {
-					// If we have switched the source state, we possibly need to insert rows for skipped choices of the last
-					// source state.
-					if (source != lastsource) {
-						// number of choices skipped = number of choices of last state - number of choices read
-						result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource]) - (lastchoice + 1);
-					}
-
-					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
-					// choices.
-					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
-						result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[i]);
-					}
-
-					// If we advanced to the next state, but skipped some choices, we have to reserve rows
-					// for them.
-					if (source != lastsource) {
-						result.choices += choice + 1;
-					} else if (choice != lastchoice) {
-						result.choices += choice - lastchoice;
-					}
-				} else {
-
-					// If we have skipped some states, we need to reserve the space for the self-loop insertion
-					// in the second pass.
-					if (source > lastsource + 1) {
-						result.numberOfNonzeroEntries += source - lastsource - 1;
-						result.choices += source - lastsource - 1;
-					} else if (source != lastsource || choice != lastchoice) {
-						// If we have switched the source state or the nondeterministic choice, we need to
-						// reserve one row more.
-						++result.choices;
-					}
-				}
-
-				// Read target and check if we encountered a state index that is bigger than all previously
-				// seen.
-				target = checked_strtol(buf, &buf);
-				if (target > result.highestStateIndex) {
-					result.highestStateIndex = target;
-				}
-
-				// Read value and check whether it's positive.
-				val = checked_strtod(buf, &buf);
-				if ((val < 0.0) || (val > 1.0)) {
-					LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
-					NondeterministicSparseTransitionParser::FirstPassResult nullResult;
-					return nullResult;
-				}
-
-				lastchoice = choice;
-				lastsource = source;
-
-				// Increase number of non-zero values.
-				result.numberOfNonzeroEntries++;
-
-				// The PRISM output format lists the name of the transition in the fourth column,
-				// but omits the fourth column if it is an internal action. In either case we can skip to the end of the line.
-				buf = forwardToLineEnd(buf, lineEndings);
-
-				buf = trimWhitespaces(buf);
-			}
-
-			if (isRewardFile) {
-				// If not all rows were filled for the last state, we need to insert them.
-				result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource] ) - (lastchoice + 1);
-
-				// If we skipped some states, we need to reserve empty rows for all their nondeterministic
-				// choices.
-				for (uint_fast64_t i = lastsource + 1; i < rewardMatrixInformation.nondeterministicChoiceIndices->size() - 1; ++i) {
-					result.choices += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[i]);
-				}
-			}
-
-			return result;
-		}
-
-		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parse(std::string const &filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation) {
+		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parse(std::string const &filename, bool isRewardFile, Result const & modelInformation) {
 
 			// Enforce locale where decimal point is '.'.
 			setlocale(LC_NUMERIC, "C");
@@ -151,14 +44,14 @@ namespace storm {
 			}
 
 			// Find out about the used line endings.
-			SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
+			SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
 
 			// Open file.
 			MappedFile file(filename.c_str());
 			char* buf = file.data;
 
 			// Perform first pass, i.e. obtain number of columns, rows and non-zero elements.
-			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.data, lineEndings, isRewardFile, rewardMatrixInformation);
+			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.data, lineEndings, isRewardFile, modelInformation);
 
 			// If first pass returned zero, the file format was wrong.
 			if (firstPass.numberOfNonzeroEntries == 0) {
@@ -176,14 +69,14 @@ namespace storm {
 
 			if (isRewardFile) {
 				// The reward matrix should match the size of the transition matrix.
-				if (firstPass.choices > rewardMatrixInformation.rowCount || (uint_fast64_t)(firstPass.highestStateIndex + 1) > rewardMatrixInformation.columnCount) {
+				if (firstPass.choices > modelInformation.transitionMatrix.getRowCount() || (uint_fast64_t)(firstPass.highestStateIndex + 1) > modelInformation.transitionMatrix.getColumnCount()) {
 					LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size.");
 					throw storm::exceptions::WrongFormatException() << "Reward matrix size exceeds transition matrix size.";
-				} else if (firstPass.choices != rewardMatrixInformation.rowCount) {
+				} else if (firstPass.choices != modelInformation.transitionMatrix.getRowCount()) {
 					LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count.");
 					throw storm::exceptions::WrongFormatException() << "Reward matrix row count does not match transition matrix row count.";
 				} else {
-					firstPass.highestStateIndex = rewardMatrixInformation.columnCount - 1;
+					firstPass.highestStateIndex = modelInformation.transitionMatrix.getColumnCount() - 1;
 				}
 			}
 
@@ -214,13 +107,13 @@ namespace storm {
 					// If we have switched the source state, we possibly need to insert the rows of the last
 					// source state.
 					if (source != lastsource) {
-						curRow += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[lastsource]) -(lastchoice + 1);
+						curRow += ((modelInformation.rowMapping)[lastsource + 1] - (modelInformation.rowMapping)[lastsource]) -(lastchoice + 1);
 					}
 
 					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 					// choices.
 					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
-						curRow += ((*rewardMatrixInformation.nondeterministicChoiceIndices)[i + 1] - (*rewardMatrixInformation.nondeterministicChoiceIndices)[i]);
+						curRow += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
 					}
 
 					// If we advanced to the next state, but skipped some choices, we have to reserve rows
@@ -279,5 +172,113 @@ namespace storm {
 			return NondeterministicSparseTransitionParser::Result(matrixBuilder.build(), rowMapping);
 		}
 
+		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndings lineEndings, bool isRewardFile, Result const & modelInformation) {
+
+			// Check file header and extract number of transitions.
+
+			// Skip the format hint if it is there.
+			buf = trimWhitespaces(buf);
+			if(buf[0] < '0' || buf[0] > '9') {
+				buf = storm::parser::forwardToNextLine(buf, lineEndings);
+			}
+
+			// Read all transitions.
+			uint_fast64_t source = 0, target = 0, choice = 0, lastchoice = 0, lastsource = 0;
+			double val = 0.0;
+			NondeterministicSparseTransitionParser::FirstPassResult result;
+
+			// Since the first line is already a new choice but is not covered below, that has to be covered here.
+			result.choices = 1;
+
+			while (buf[0] != '\0') {
+
+				// Read source state and choice.
+				source = checked_strtol(buf, &buf);
+
+				// Read the name of the nondeterministic choice.
+				choice = checked_strtol(buf, &buf);
+
+				// Check if we encountered a state index that is bigger than all previously seen.
+				if (source > result.highestStateIndex) {
+					result.highestStateIndex = source;
+				}
+
+				if (isRewardFile) {
+					// If we have switched the source state, we possibly need to insert rows for skipped choices of the last
+					// source state.
+					if (source != lastsource) {
+						// number of choices skipped = number of choices of last state - number of choices read
+						result.choices += ((modelInformation.rowMapping)[lastsource + 1] - (modelInformation.rowMapping)[lastsource]) - (lastchoice + 1);
+					}
+
+					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
+					// choices.
+					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
+						result.choices += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
+					}
+
+					// If we advanced to the next state, but skipped some choices, we have to reserve rows
+					// for them.
+					if (source != lastsource) {
+						result.choices += choice + 1;
+					} else if (choice != lastchoice) {
+						result.choices += choice - lastchoice;
+					}
+				} else {
+
+					// If we have skipped some states, we need to reserve the space for the self-loop insertion
+					// in the second pass.
+					if (source > lastsource + 1) {
+						result.numberOfNonzeroEntries += source - lastsource - 1;
+						result.choices += source - lastsource - 1;
+					} else if (source != lastsource || choice != lastchoice) {
+						// If we have switched the source state or the nondeterministic choice, we need to
+						// reserve one row more.
+						++result.choices;
+					}
+				}
+
+				// Read target and check if we encountered a state index that is bigger than all previously
+				// seen.
+				target = checked_strtol(buf, &buf);
+				if (target > result.highestStateIndex) {
+					result.highestStateIndex = target;
+				}
+
+				// Read value and check whether it's positive.
+				val = checked_strtod(buf, &buf);
+				if ((val < 0.0) || (val > 1.0)) {
+					LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
+					NondeterministicSparseTransitionParser::FirstPassResult nullResult;
+					return nullResult;
+				}
+
+				lastchoice = choice;
+				lastsource = source;
+
+				// Increase number of non-zero values.
+				result.numberOfNonzeroEntries++;
+
+				// The PRISM output format lists the name of the transition in the fourth column,
+				// but omits the fourth column if it is an internal action. In either case we can skip to the end of the line.
+				buf = forwardToLineEnd(buf, lineEndings);
+
+				buf = trimWhitespaces(buf);
+			}
+
+			if (isRewardFile) {
+				// If not all rows were filled for the last state, we need to insert them.
+				result.choices += ((modelInformation.rowMapping)[lastsource + 1] - (modelInformation.rowMapping)[lastsource] ) - (lastchoice + 1);
+
+				// If we skipped some states, we need to reserve empty rows for all their nondeterministic
+				// choices.
+				for (uint_fast64_t i = lastsource + 1; i < modelInformation.rowMapping.size() - 1; ++i) {
+					result.choices += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
+				}
+			}
+
+			return result;
+		}
+
 	}  // namespace parser
 }  // namespace storm
diff --git a/src/parser/NondeterministicSparseTransitionParser.h b/src/parser/NondeterministicSparseTransitionParser.h
index 34fc3f397..3df4834ae 100644
--- a/src/parser/NondeterministicSparseTransitionParser.h
+++ b/src/parser/NondeterministicSparseTransitionParser.h
@@ -39,6 +39,12 @@ namespace storm {
 			 */
 			struct Result {
 
+				// Constructs an empty Result.
+				Result() : transitionMatrix(), rowMapping() {
+					// Intentionally left empty.
+				}
+
+				// Constructs a Result, initializing its members with the given values.
 				Result(storm::storage::SparseMatrix<double> transitionMatrix, std::vector<uint_fast64_t> rowMapping) : transitionMatrix(transitionMatrix), rowMapping(rowMapping) {
 					// Intentionally left empty.
 				}
@@ -52,16 +58,22 @@ namespace storm {
 			};
 
 			/*!
-			 *	@brief	Load a nondeterministic transition system from file and create a
-			 *	sparse adjacency matrix whose entries represent the weights of the edges
+			 * @brief Load a nondeterministic transition system from file and create a
+			 *        sparse adjacency matrix whose entries represent the weights of the edges
+			 *
+			 * @param filename The path of file to be parsed.
 			 */
-			static Result parseNondeterministicTransitions(std::string const &filename);
+			static Result parseNondeterministicTransitions(std::string const & filename);
 
 			/*!
 			 *	@brief	Load a nondeterministic transition system from file and create a
 			 *	sparse adjacency matrix whose entries represent the weights of the edges
+			 *
+			 * @param filename The path of file to be parsed.
+			 * @param modelInformation The information about the transition structure of nondeterministic model in which the transition rewards shall be used.
+			 * @return A struct containing the parsed file contents, i.e. the transition reward matrix and the mapping between its rows and the states of the model.
 			 */
-			static Result parseNondeterministicTransitionRewards(std::string const &filename, RewardMatrixInformationStruct const& rewardMatrixInformation);
+			static Result parseNondeterministicTransitionRewards(std::string const & filename, Result const & modelInformation);
 
 		private:
 
@@ -79,7 +91,7 @@ namespace storm {
 			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 			 * @return A structure representing the result of the first pass.
 			 */
-			static FirstPassResult firstPass(char* buffer, SupportedLineEndingsEnum lineEndings, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation);
+			static FirstPassResult firstPass(char* buffer, SupportedLineEndings lineEndings, bool isRewardFile, Result const & modelInformation);
 
 			/*!
 			 * The main parsing routine.
@@ -88,10 +100,10 @@ namespace storm {
 			 * @param filename The path of file to be parsed.
 			 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
 			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
-			 * @param rewardMatrixInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
+			 * @param modelInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
 			 * @return A SparseMatrix containing the parsed file contents.
 			 */
-			static Result parse(std::string const& filename, bool isRewardFile, RewardMatrixInformationStruct const& rewardMatrixInformation);
+			static Result parse(std::string const& filename, bool isRewardFile, Result const & modelInformation);
 
 		};
 	
diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp
index b1b0c6e79..9e4113445 100644
--- a/src/parser/Parser.cpp
+++ b/src/parser/Parser.cpp
@@ -11,6 +11,7 @@
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
 #include "src/utility/OsDetection.h"
+#include "src/parser/MappedFile.h"
 
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
@@ -91,7 +92,7 @@ char* trimWhitespaces(char* buf) {
 /*!
  * @briefs Analyzes the given file and tries to find out the used file endings.
  */
-SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported) {
+SupportedLineEndings findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported) {
 	MappedFile fileMap(fileName.c_str());
 	char* buf = nullptr;
 	char* const bufferEnd = fileMap.dataend;
@@ -100,11 +101,11 @@ SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool t
 		if (*buf == '\r') {
 			// check for following \n
 			if (((buf + sizeof(char)) < bufferEnd) && (*(buf + sizeof(char)) == '\n')) {
-				return SupportedLineEndingsEnum::SlashRN;
+				return SupportedLineEndings::SlashRN;
 			}
-			return SupportedLineEndingsEnum::SlashR;
+			return SupportedLineEndings::SlashR;
 		} else if (*buf == '\n') {
-			return SupportedLineEndingsEnum::SlashN;
+			return SupportedLineEndings::SlashN;
 		}
 	}
 
@@ -114,25 +115,25 @@ SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool t
 	}
 	LOG4CPLUS_WARN(logger, "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n");
 
-	return SupportedLineEndingsEnum::Unsupported;
+	return SupportedLineEndings::Unsupported;
 }
 
 /*!
  * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
  */
-char* forwardToLineEnd(char* buffer, SupportedLineEndingsEnum lineEndings) {
+char* forwardToLineEnd(char* buffer, SupportedLineEndings lineEndings) {
 	switch (lineEndings) {
-		case SupportedLineEndingsEnum::SlashN:
+		case SupportedLineEndings::SlashN:
 			return buffer + strcspn(buffer, "\n\0");
 			break;
-		case SupportedLineEndingsEnum::SlashR:
+		case SupportedLineEndings::SlashR:
 			return buffer + strcspn(buffer, "\r\0");
 			break;
-		case SupportedLineEndingsEnum::SlashRN:
+		case SupportedLineEndings::SlashRN:
 			return buffer + strcspn(buffer, "\r\0");
 			break;
 		default:
-		case SupportedLineEndingsEnum::Unsupported:
+		case SupportedLineEndings::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
 			throw;
 			break;
@@ -143,19 +144,19 @@ char* forwardToLineEnd(char* buffer, SupportedLineEndingsEnum lineEndings) {
 /*!
  * @brief Encapsulates the usage of function @strchr to forward to the next line
  */
-char* forwardToNextLine(char* buffer, SupportedLineEndingsEnum lineEndings) {
+char* forwardToNextLine(char* buffer, SupportedLineEndings lineEndings) {
 	switch (lineEndings) {
-		case SupportedLineEndingsEnum::SlashN:
+		case SupportedLineEndings::SlashN:
 			return strchr(buffer, '\n') + 1;  
 			break;
-		case SupportedLineEndingsEnum::SlashR:
+		case SupportedLineEndings::SlashR:
 			return strchr(buffer, '\r') + 1;  
 			break;
-		case SupportedLineEndingsEnum::SlashRN:
+		case SupportedLineEndings::SlashRN:
 			return strchr(buffer, '\r') + 2;
 			break;
 		default:
-		case SupportedLineEndingsEnum::Unsupported:
+		case SupportedLineEndings::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
 			throw;
 			break;
@@ -168,26 +169,26 @@ char* forwardToNextLine(char* buffer, SupportedLineEndingsEnum lineEndings) {
  * @param targetBuffer The Target for the hint, must be at least 64 bytes long
  * @param buffer The Source Buffer from which the Model Hint will be read
  */
-void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, SupportedLineEndingsEnum lineEndings) {
+void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, SupportedLineEndings lineEndings) {
 	if (targetBufferSize <= 4) {
 		throw;
 	}
 	switch (lineEndings) {
-		case SupportedLineEndingsEnum::SlashN:
+		case SupportedLineEndings::SlashN:
 #ifdef WINDOWS					
 			sscanf_s(buffer, "%60s\n", targetBuffer, targetBufferSize);
 #else
 			sscanf(buffer, "%60s\n", targetBuffer);
 #endif
 			break;
-		case SupportedLineEndingsEnum::SlashR:
+		case SupportedLineEndings::SlashR:
 #ifdef WINDOWS					
 			sscanf_s(buffer, "%60s\r", targetBuffer, sizeof(targetBufferSize));
 #else
 			sscanf(buffer, "%60s\r", targetBuffer);
 #endif
 			break;
-		case SupportedLineEndingsEnum::SlashRN:
+		case SupportedLineEndings::SlashRN:
 #ifdef WINDOWS					
 			sscanf_s(buffer, "%60s\r\n", targetBuffer, sizeof(targetBufferSize));
 #else
@@ -195,7 +196,7 @@ void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char c
 #endif
 			break;
 		default:
-		case SupportedLineEndingsEnum::Unsupported:
+		case SupportedLineEndings::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
 			throw;
 			break;
@@ -205,13 +206,13 @@ void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char c
 /*!
  * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
  */
-void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, SupportedLineEndingsEnum lineEndings) {
+void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, SupportedLineEndings lineEndings) {
 	if (targetBufferSize < 5) {
 		LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed Target Buffer is too small.");
 		throw;
 	}
 	switch (lineEndings) {
-		case SupportedLineEndingsEnum::SlashN: {
+		case SupportedLineEndings::SlashN: {
 			char source[] = " \n\t";
 #ifdef WINDOWS			
 			strncpy(targetBuffer, targetBufferSize, source, sizeof(source));
@@ -220,7 +221,7 @@ void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSi
 #endif
 			break;
 											   }
-		case SupportedLineEndingsEnum::SlashR: {
+		case SupportedLineEndings::SlashR: {
 			char source[] = " \r\t";
 #ifdef WINDOWS			
 			strncpy(targetBuffer, targetBufferSize, source, sizeof(source));
@@ -229,7 +230,7 @@ void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSi
 #endif
 			break;
 											   }
-		case SupportedLineEndingsEnum::SlashRN: {
+		case SupportedLineEndings::SlashRN: {
 			char source[] = " \r\n\t";
 #ifdef WINDOWS			
 			strncpy(targetBuffer, targetBufferSize, source, sizeof(source));
@@ -239,7 +240,7 @@ void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSi
 			break;
 												}
 		default:
-		case SupportedLineEndingsEnum::Unsupported:
+		case SupportedLineEndings::Unsupported:
 			// This Line will never be reached as the Parser would have thrown already.
 			LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed lineEndings were Unsupported. Check your input file.");
 			throw;
@@ -247,87 +248,6 @@ void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSi
 	}
 }
 
-/*!
- *	Will stat the given file, open it and map it to memory.
- *	If anything of this fails, an appropriate exception is raised
- *	and a log entry is written.
- *	@param filename file to be opened
- */
-MappedFile::MappedFile(const char* filename) {
-#if defined LINUX || defined MACOSX
-	/*
-	 *	Do file mapping for reasonable systems.
-	 *	stat64(), open(), mmap()
-	 */
-#ifdef MACOSX
-	if (stat(filename, &(this->st)) != 0) {
-#else
-	if (stat64(filename, &(this->st)) != 0) {
-#endif
-		LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): Probably, this file does not exist.");
-		throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist.";
-	}
-	this->file = open(filename, O_RDONLY);
-
-	if (this->file < 0) {
-		LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): Probably, we may not read this file.");
-		throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file.";
-	}
-
-	this->data = reinterpret_cast<char*>(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0));
-	if (this->data == reinterpret_cast<char*>(-1)) {
-		close(this->file);
-		LOG4CPLUS_ERROR(logger, "Error in mmap(" << filename << "): " << std::strerror(errno));
-		throw exceptions::FileIoException() << "MappedFile Error in mmap(): " << std::strerror(errno);
-	}
-	this->dataend = this->data + this->st.st_size;
-#elif defined WINDOWS
-	/*
-	 *	Do file mapping for windows.
-	 *	_stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile()
-	 */
-	if (_stat64(filename, &(this->st)) != 0) {
-		LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist.");
-		throw exceptions::FileIoException("MappedFile Error in stat(): Probably, this file does not exist.");
-	}
-
-	this->file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-	if (this->file == INVALID_HANDLE_VALUE) {
-		LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << "): Probably, we may not read this file.");
-		throw exceptions::FileIoException("MappedFile Error in CreateFileA(): Probably, we may not read this file.");
-	}
-
-	this->mapping = CreateFileMappingA(this->file, NULL, PAGE_READONLY, (DWORD)(st.st_size >> 32), (DWORD)st.st_size, NULL);
-	if (this->mapping == NULL) {
-		CloseHandle(this->file);
-		LOG4CPLUS_ERROR(logger, "Error in CreateFileMappingA(" << filename << ").");
-		throw exceptions::FileIoException("MappedFile Error in CreateFileMappingA().");
-	}
-
-	this->data = static_cast<char*>(MapViewOfFile(this->mapping, FILE_MAP_READ, 0, 0, this->st.st_size));
-	if (this->data == NULL) {
-		CloseHandle(this->mapping);
-		CloseHandle(this->file);
-		LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ").");
-		throw exceptions::FileIoException("MappedFile Error in MapViewOfFile().");
-	}
-	this->dataend = this->data + this->st.st_size;
-#endif
-}
-
-/*!
- *	Will unmap the data and close the file.
- */
-MappedFile::~MappedFile() {
-#if defined LINUX || defined MACOSX
-	munmap(this->data, this->st.st_size);
-	close(this->file);
-#elif defined WINDOWS
-	CloseHandle(this->mapping);
-	CloseHandle(this->file);
-#endif
-}
-
 } // namespace parser
 
 } // namespace storm
diff --git a/src/parser/Parser.h b/src/parser/Parser.h
index b2cfb0677..962f699eb 100644
--- a/src/parser/Parser.h
+++ b/src/parser/Parser.h
@@ -16,161 +16,78 @@
 
 namespace storm {
 
-/*!
- *	@brief Contains all file parser and helper classes.
- *
- *	This namespace contains everything needed to load data files (like
- *	atomic propositions, transition systems, formulas, ...) including
- *	methods for efficient file access (see MappedFile).
- */
-namespace parser {
-
-struct RewardMatrixInformationStruct {
-	RewardMatrixInformationStruct() : rowCount(0), columnCount(0), nondeterministicChoiceIndices(nullptr) {
-		// Intentionally left empty.
-	}
-
-	RewardMatrixInformationStruct(uint_fast64_t rowCount, uint_fast64_t columnCount, std::vector<uint_fast64_t> const * const nondeterministicChoiceIndices)
-	: rowCount(rowCount), columnCount(columnCount), nondeterministicChoiceIndices(nondeterministicChoiceIndices) {
-		// Intentionally left empty.
-	}
-
-	uint_fast64_t rowCount;
-	uint_fast64_t columnCount;
-	std::vector<uint_fast64_t> const * const nondeterministicChoiceIndices;
-};
-
-/*!
- *	@brief Opens a file and maps it to memory providing a char*
- *	containing the file content.
- *
- *	This class is a very simple interface to read files efficiently.
- *	The given file is opened and mapped to memory using mmap().
- *	The public member data is a pointer to the actual file content.
- *	Using this method, the kernel will take care of all buffering. This is
- *	most probably much more efficient than doing this manually.
- */
-
-#if !defined LINUX && !defined MACOSX && !defined WINDOWS
-#error Platform not supported
-#endif
-
-class MappedFile {
-	private:
-#if defined LINUX || defined MACOSX
-		/*!
-		 *	@brief file descriptor obtained by open().
-		 */
-		int file;
-#elif defined WINDOWS
-		HANDLE file;
-		HANDLE mapping;
-#endif
-
-#if defined LINUX
-		/*!
-		 *	@brief stat information about the file.
-		 */
-		struct stat64 st;
-#elif defined MACOSX
-		/*!
-		 *	@brief stat information about the file.
-		 */
-		struct stat st;
-#elif defined WINDOWS
-		/*!
-		 *	@brief stat information about the file.
-		 */
-		struct __stat64 st;
-#endif
-
-	public:
-		/*!
-		 *	@brief pointer to actual file content.
-		 */
-		char* data;
-		
-		/*!
-		 *	@brief pointer to end of file content.
-		 */
-		char* dataend;
-
 	/*!
-	 *	@brief Constructor of MappedFile.
+	 *	@brief Contains all file parsers and helper classes.
+	 *
+	 *	This namespace contains everything needed to load data files (like
+	 *	atomic propositions, transition systems, formulas, etc.) including
+	 *	methods for efficient file access (see MappedFile).
 	 */
-	MappedFile(const char* filename);
-	
+	namespace parser {
+
 	/*!
-	 *	@brief Destructor of MappedFile.
+	 *	@brief Parses integer and checks, if something has been parsed.
 	 */
-	~MappedFile();
-};
-
-/*!
- *	@brief Parses integer and checks, if something has been parsed.
- */
-uint_fast64_t checked_strtol(const char* str, char** end);
-
-/*!
- *	@brief Parses floating point and checks, if something has been parsed.
- */
-double checked_strtod(const char* str, char** end);
-
-/*!
- * @brief Skips all non whitespace characters until the next whitespace.
- */
-char* skipWord(char* buf);
+	uint_fast64_t checked_strtol(const char* str, char** end);
 
-/*!
- *	@brief Skips common whitespaces in a string.
- */
-char* trimWhitespaces(char* buf);
+	/*!
+	 *	@brief Parses floating point and checks, if something has been parsed.
+	 */
+	double checked_strtod(const char* str, char** end);
 
-/*!
- *  @brief Tests whether the given file exists and is readable.
- */
-bool fileExistsAndIsReadable(const char* fileName);
+	/*!
+	 * @brief Skips all non whitespace characters until the next whitespace.
+	 */
+	char* skipWord(char* buf);
 
-/*!
- * @brief Enum Class Type containing all supported file endings.
- */
-enum class SupportedLineEndingsEnum : unsigned short {
-	Unsupported = 0,
-	SlashR,
-	SlashN,
-	SlashRN
-};
-
-/*!
- * @briefs Analyzes the given file and tries to find out the used line endings.
- */
-storm::parser::SupportedLineEndingsEnum findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false);
+	/*!
+	 *	@brief Skips common whitespaces in a string.
+	 */
+	char* trimWhitespaces(char* buf);
 
-/*!
- * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
- */
-char* forwardToLineEnd(char* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+	/*!
+	 *  @brief Tests whether the given file exists and is readable.
+	 */
+	bool fileExistsAndIsReadable(const char* fileName);
 
-/*!
- * @brief Encapsulates the usage of function @strchr to forward to the next line
- */
-char* forwardToNextLine(char* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+	/*!
+	 * @brief Enum Class Type containing all supported file endings.
+	 */
+	enum class SupportedLineEndings : unsigned short {
+		Unsupported = 0,
+		SlashR,
+		SlashN,
+		SlashRN
+	};
 
-/*!
- * @brief Encapsulates the usage of function @sscanf to scan for the model type hint
- * @param targetBuffer The Target for the hint, should be at least 64 bytes long
- * @param buffer The Source Buffer from which the Model Hint will be read
+	/*!
+	 * @briefs Analyzes the given file and tries to find out the used line endings.
+	 */
+	storm::parser::SupportedLineEndings findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false);
 
- */
-void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndingsEnum lineEndings);
+	/*!
+	 * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
+	 */
+	char* forwardToLineEnd(char* buffer, storm::parser::SupportedLineEndings lineEndings);
 
-/*!
- * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
- */
-void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndingsEnum lineEndings);
+	/*!
+	 * @brief Encapsulates the usage of function @strchr to forward to the next line
+	 */
+	char* forwardToNextLine(char* buffer, storm::parser::SupportedLineEndings lineEndings);
 
-} // namespace parser
+	/*!
+	 * @brief Encapsulates the usage of function @sscanf to scan for the model type hint
+	 * @param targetBuffer The Target for the hint, should be at least 64 bytes long
+	 * @param buffer The Source Buffer from which the Model Hint will be read
+	 */
+	void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndings lineEndings);
+	
+	/*!
+	 * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
+	 */
+	void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndings lineEndings);
 
+	} // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_PARSER_H_ */
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index 9a4e34be6..a0bd62ce3 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -12,6 +12,7 @@
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
 #include "src/parser/Parser.h"
+#include "src/parser/MappedFile.h"
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;

From fe7afc727f8393be5f14a9373656de21674604b9 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Thu, 30 Jan 2014 10:29:57 +0100
Subject: [PATCH 013/147] Second part of the refactoring of Parser.cpp/.h

- Eliminated the need for SupportedLineEndings (I hope...should work on all os, but have only tested this on linux)
- Moved fileExistsAndIsReadable to MappedFile
- Removed scanForModelHint and replaced it with its contents at the one point where is was used in the AutoParser
- Moved and renamed remaining part of Parser.cpp/.h to src/utility/cstring.cpp/.h
|- New namespace of the cstring manipulation functions is storm::utility::cstring
|- Used a using namespace storm::utility::cstring to eliminate the full namespace specification within the needing parsers. This keeps the code readable.
- Threw out some unnessesary includes.

Next up: Commenting and making things look nice.


Former-commit-id: c983d1e1a259b35e04bcf57d969870332e169018
---
 .../AtomicPropositionLabelingParser.cpp       |  35 +--
 src/parser/AutoParser.cpp                     |  19 +-
 src/parser/AutoParser.h                       |   8 +
 src/parser/CslParser.h                        |   2 -
 src/parser/DeterministicModelParser.h         |   1 -
 .../DeterministicSparseTransitionParser.cpp   |  18 +-
 .../DeterministicSparseTransitionParser.h     |   4 +-
 src/parser/LtlParser.h                        |   1 -
 src/parser/MappedFile.cpp                     |   8 +-
 src/parser/MappedFile.h                       |   6 +
 .../MarkovAutomatonSparseTransitionParser.cpp |  38 +--
 .../MarkovAutomatonSparseTransitionParser.h   |   7 +-
 src/parser/NondeterministicModelParser.h      |   1 -
 ...NondeterministicSparseTransitionParser.cpp |  23 +-
 .../NondeterministicSparseTransitionParser.h  |   4 +-
 src/parser/Parser.cpp                         | 253 ------------------
 src/parser/Parser.h                           |  93 -------
 src/parser/PrctlParser.h                      |   2 -
 src/parser/SparseStateRewardParser.cpp        |   6 +-
 src/utility/cstring.cpp                       |  95 +++++++
 src/utility/cstring.h                         |  53 ++++
 .../parser/MarkovAutomatonParserTest.cpp      |   2 +-
 22 files changed, 246 insertions(+), 433 deletions(-)
 delete mode 100644 src/parser/Parser.cpp
 delete mode 100644 src/parser/Parser.h
 create mode 100644 src/utility/cstring.cpp
 create mode 100644 src/utility/cstring.h

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index aaca0d7a3..ad5543476 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -11,7 +11,7 @@
 #include <string>
 #include <iostream>
 
-#include "src/parser/Parser.h"
+#include "src/utility/cstring.h"
 #include "src/parser/MappedFile.h"
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
@@ -23,25 +23,20 @@ extern log4cplus::Logger logger;
 namespace storm {
 	namespace parser {
 
+		using namespace storm::utility::cstring;
+
 		storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const & filename) {
 
 			// Open the given file.
-			if (!storm::parser::fileExistsAndIsReadable(filename.c_str())) {
+			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
 				throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process.";
 			}
 
-			// Find out about the used line endings.
-			SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
-
 			MappedFile file(filename.c_str());
 			char* buf = file.data;
 
 			// First pass: Count the number of propositions.
-			// Convert the line endings into a string containing all whitespace characters, that separate words in the file.
-			char separator[5];
-			storm::parser::getMatchingSeparatorString(separator, sizeof(separator), lineEndings);
-
 			bool foundDecl = false, foundEnd = false;
 			uint_fast32_t proposition_count = 0;
 			size_t cnt = 0;
@@ -49,11 +44,12 @@ namespace storm {
 			// Iterate over tokens until we hit #END or the end of the file.
 			while(buf[0] != '\0') {
 
-				// Move the buffer pointer to the separator.
+				//Move the buffer to the beginning of the next word.
 				buf += cnt;
+				buf = trimWhitespaces(buf);
 
 				// Get the number of characters until the next separator.
-				cnt = strcspn(buf, separator);
+				cnt = skipWord(buf) - buf;
 				if (cnt > 0) {
 
 					// If the next token is #DECLARATION: Just skip it.
@@ -67,10 +63,6 @@ namespace storm {
 						break;
 					}
 					proposition_count++;
-				} else {
-
-					// If the next character is a separator, skip it.
-					buf++;
 				}
 			}
 
@@ -98,11 +90,12 @@ namespace storm {
 			// As we already checked the file header, we know that #DECLARATION and #END are tokens in the character stream.
 			while(buf[0] != '\0') {
 
-				// Move the buffer pointer to the separator.
+				//Move the buffer to the beginning of the next word.
 				buf += cnt;
+				buf = trimWhitespaces(buf);
 
-				// The number of characters until the next separator.
-				cnt = strcspn(buf, separator);
+				// Get the number of characters until the next separator.
+				cnt = skipWord(buf) - buf;
 
 				if (cnt >= sizeof(proposition)) {
 
@@ -122,10 +115,6 @@ namespace storm {
 					strncpy(proposition, buf, cnt);
 					proposition[cnt] = '\0';
 					labeling.addAtomicProposition(proposition);
-				} else {
-
-					// The next character is a separator, thus move one step forward.
-					buf++;
 				}
 			}
 
@@ -143,7 +132,7 @@ namespace storm {
 				// Stop at the end of the line.
 				node = checked_strtol(buf, &buf);
 				while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
-					cnt = strcspn(buf, separator);
+					cnt = skipWord(buf) - buf;
 					if (cnt == 0) {
 
 						// The next character is a separator.
diff --git a/src/parser/AutoParser.cpp b/src/parser/AutoParser.cpp
index 91e28c9d2..d9d6bcfa5 100644
--- a/src/parser/AutoParser.cpp
+++ b/src/parser/AutoParser.cpp
@@ -7,7 +7,6 @@
 
 #include "src/parser/AutoParser.h"
 
-#include "src/parser/Parser.h"
 #include "src/parser/MappedFile.h"
 
 #include "src/parser/DeterministicModelParser.h"
@@ -15,9 +14,14 @@
 #include "src/parser/MarkovAutomatonParser.h"
 #include "src/exceptions/WrongFormatException.h"
 
+#include "src/utility/cstring.h"
+#include "src/utility/OsDetection.h"
+
 namespace storm {
 	namespace parser {
 
+		using namespace storm::utility::cstring;
+
 		std::shared_ptr<storm::models::AbstractModel<double>> AutoParser::parseModel(std::string const & transitionSystemFile,
 																					 std::string const & labelingFile,
 																					 std::string const & stateRewardFile,
@@ -68,17 +72,18 @@ namespace storm {
 		storm::models::ModelType AutoParser::analyzeHint(const std::string& filename) {
 			storm::models::ModelType hintType = storm::models::Unknown;
 
-			// Find out the line endings used within the file.
-			storm::parser::SupportedLineEndings lineEndings = storm::parser::findUsedLineEndings(filename);
-
 			// Open the file.
 			MappedFile file(filename.c_str());
 			char* buf = file.data;
 
 			// Find and read in the hint.
-			char hint[128];
-			// %20s => The input hint can be AT MOST 120 chars long.
-			storm::parser::scanForModelHint(hint, sizeof(hint), buf, lineEndings);
+			char hint[65];
+			// %60s => The input hint can be AT MOST 60 chars long.
+		#ifdef WINDOWS
+			sscanf_s(buf, "%60s", hint, sizeof(hint));
+		#else
+			sscanf(buf, "%60s", hint);
+		#endif
 
 			for (char* c = hint; *c != '\0'; c++) *c = toupper(*c);
 
diff --git a/src/parser/AutoParser.h b/src/parser/AutoParser.h
index 2e52fad59..88df0d076 100644
--- a/src/parser/AutoParser.h
+++ b/src/parser/AutoParser.h
@@ -6,6 +6,14 @@
 #include <string>
 
 namespace storm {
+
+	/*!
+	 *	@brief Contains all file parsers and helper classes.
+	 *
+	 *	This namespace contains everything needed to load data files (like
+	 *	atomic propositions, transition systems, formulas, etc.) including
+	 *	methods for efficient file access (see MappedFile).
+	 */
 	namespace parser {
 
 		class AutoParser {
diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h
index 8dd4315d3..2ef4c64e3 100644
--- a/src/parser/CslParser.h
+++ b/src/parser/CslParser.h
@@ -8,8 +8,6 @@
 #ifndef STORM_PARSER_CSLPARSER_H_
 #define STORM_PARSER_CSLPARSER_H_
 
-#include "Parser.h"
-
 #include "src/formula/Csl.h"
 #include <functional>
 
diff --git a/src/parser/DeterministicModelParser.h b/src/parser/DeterministicModelParser.h
index 3fc840c5e..2143ea820 100644
--- a/src/parser/DeterministicModelParser.h
+++ b/src/parser/DeterministicModelParser.h
@@ -8,7 +8,6 @@
 #ifndef STORM_PARSER_DETERMINISTICMODELPARSER_H_
 #define STORM_PARSER_DETERMINISTICMODELPARSER_H_
 
-#include "src/parser/Parser.h"
 #include "src/models/Dtmc.h"
 #include "src/models/Ctmc.h"
 
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 666a45039..a127ebde0 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -15,6 +15,7 @@
 #include <string>
 
 #include "src/utility/constants.h"
+#include "src/utility/cstring.h"
 #include "src/parser/MappedFile.h"
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
@@ -27,6 +28,8 @@ extern log4cplus::Logger logger;
 namespace storm {
 	namespace parser {
 
+		using namespace storm::utility::cstring;
+
 		storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename) {
 
 			storm::storage::SparseMatrix<double> emptyMatrix;
@@ -43,21 +46,18 @@ namespace storm {
 			// Enforce locale where decimal point is '.'.
 				setlocale(LC_NUMERIC, "C");
 
-				if (!fileExistsAndIsReadable(filename.c_str())) {
+				if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
 					throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
 				}
 
-				// Find out about the used line endings.
-				SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
-
 				// Open file.
 				MappedFile file(filename.c_str());
 				char* buf = file.data;
 
 				// Perform first pass, i.e. count entries that are not zero.
 				bool insertDiagonalEntriesIfMissing = !isRewardFile;
-				DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, lineEndings, insertDiagonalEntriesIfMissing);
+				DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, insertDiagonalEntriesIfMissing);
 
 				LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
 
@@ -72,7 +72,8 @@ namespace storm {
 				// Skip the format hint if it is there.
 				buf = trimWhitespaces(buf);
 				if(buf[0] < '0' || buf[0] > '9') {
-					buf = storm::parser::forwardToNextLine(buf, lineEndings);
+					buf = forwardToLineEnd(buf);
+					buf = trimWhitespaces(buf);
 				}
 
 				if(isRewardFile) {
@@ -191,14 +192,15 @@ namespace storm {
 				return resultMatrix.build();
 		}
 
-		DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndings lineEndings, bool insertDiagonalEntriesIfMissing) {
+		DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, bool insertDiagonalEntriesIfMissing) {
 
 			DeterministicSparseTransitionParser::FirstPassResult result;
 
 			// Skip the format hint if it is there.
 			buf = trimWhitespaces(buf);
 			if(buf[0] < '0' || buf[0] > '9') {
-				buf = storm::parser::forwardToNextLine(buf, lineEndings);
+				buf = forwardToLineEnd(buf);
+				buf = trimWhitespaces(buf);
 			}
 
 			 // Check all transitions for non-zero diagonal entries and deadlock states.
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index a9147f763..d89490bee 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -2,7 +2,6 @@
 #define STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
 
 #include "src/storage/SparseMatrix.h"
-#include "src/parser/Parser.h"
 
 namespace storm {
 
@@ -59,11 +58,10 @@ private:
 	 * transitions and the maximum node id.
 	 *
 	 * @param buffer The buffer that cointains the input.
-	 * @param lineEndings The line endings that are to be used while parsing.
 	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 	 * @return A structure representing the result of the first pass.
 	 */
-	static FirstPassResult firstPass(char* buffer, SupportedLineEndings lineEndings, bool insertDiagonalEntriesIfMissing = true);
+	static FirstPassResult firstPass(char* buffer, bool insertDiagonalEntriesIfMissing = true);
 
 	/*
 	 * The main parsing routine.
diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h
index 20e82896b..cefcd8f2c 100644
--- a/src/parser/LtlParser.h
+++ b/src/parser/LtlParser.h
@@ -8,7 +8,6 @@
 #ifndef STORM_PARSER_LTLPARSER_H_
 #define STORM_PARSER_LTLPARSER_H_
 
-#include "Parser.h"
 #include "src/formula/Ltl.h"
 
 namespace storm {
diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp
index 69d9fd4a9..c1c654aa7 100644
--- a/src/parser/MappedFile.cpp
+++ b/src/parser/MappedFile.cpp
@@ -11,9 +11,6 @@
 #include <cstring>
 #include <fcntl.h>
 
-#include <iostream>
-#include <string>
-
 #include <boost/integer/integer_mask.hpp>
 
 #include "src/exceptions/FileIoException.h"
@@ -96,6 +93,11 @@ namespace storm {
 			CloseHandle(this->file);
 		#endif
 		}
+
+		bool MappedFile::fileExistsAndIsReadable(const char* fileName) {
+			std::ifstream fin(fileName);
+			return fin.good();
+		}
 	} // namespace parser
 } // namespace storm
 
diff --git a/src/parser/MappedFile.h b/src/parser/MappedFile.h
index 8b66b0fde..da2df3c3d 100644
--- a/src/parser/MappedFile.h
+++ b/src/parser/MappedFile.h
@@ -48,6 +48,12 @@ namespace storm {
 			 */
 			~MappedFile();
 
+			/*!
+			 *  @brief Tests whether the given file exists and is readable.
+			 *  @return True iff the file exists and is readable.
+			 */
+			static bool fileExistsAndIsReadable(const char* fileName);
+
 			/*!
 			 *	@brief pointer to actual file content.
 			 */
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index de950aab8..a899632a4 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -2,13 +2,17 @@
 
 #include "src/settings/Settings.h"
 #include "src/exceptions/WrongFormatException.h"
-#include "MappedFile.h"
+#include "src/parser/MappedFile.h"
+#include "src/utility/cstring.h"
+
 
 namespace storm {
 
 namespace parser {
 
-MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf, SupportedLineEndings lineEndings) {
+using namespace storm::utility::cstring;
+
+MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf) {
 	MarkovAutomatonSparseTransitionParser::FirstPassResult result;
 
 	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
@@ -16,7 +20,8 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 	// Skip the format hint if it is there.
 	buf = trimWhitespaces(buf);
 	if(buf[0] < '0' || buf[0] > '9') {
-		buf = storm::parser::forwardToNextLine(buf, lineEndings);
+		buf = forwardToLineEnd(buf);
+		buf = trimWhitespaces(buf);
 	}
 
 	// Now read the transitions.
@@ -84,7 +89,8 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 			stateHasProbabilisticChoice = true;
 		}
 
-		buf = forwardToNextLine(buf, lineEndings);
+		// Go to the next line where the transitions start.
+		buf = forwardToNextLine(buf);
 
 		// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
 		bool hasSuccessorState = false;
@@ -131,7 +137,7 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 				// As we found a new successor, we need to increase the number of nonzero entries.
 				++result.numberOfNonzeroEntries;
 
-				buf = forwardToNextLine(buf, lineEndings);
+				buf = forwardToNextLine(buf);
 			} else {
 				// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
 				// to the buffer, because we still need to read the new source state.
@@ -143,13 +149,17 @@ MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTran
 	return result;
 }
 
-MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, SupportedLineEndings lineEndings, FirstPassResult const& firstPassResult) {
+MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, FirstPassResult const& firstPassResult) {
 	ResultType result(firstPassResult);
 
 	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 
-	// Skip the format hint.
-	buf = storm::parser::forwardToNextLine(buf, lineEndings);
+	// Skip the format hint if it is there.
+	buf = trimWhitespaces(buf);
+	if(buf[0] < '0' || buf[0] > '9') {
+		buf = forwardToLineEnd(buf);
+		buf = trimWhitespaces(buf);
+	}
 
 	// Now read the transitions.
 	uint_fast64_t source, target = 0;
@@ -195,7 +205,8 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 			isMarkovianChoice = false;
 		}
 
-		buf = forwardToNextLine(buf, lineEndings);
+		// Go to the next line where the transitions start.
+		buf = forwardToNextLine(buf);
 
 		// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
 		bool encounteredNewDistribution = false;
@@ -226,7 +237,7 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 					result.exitRates[source] += val;
 				}
 
-				buf = forwardToNextLine(buf, lineEndings);
+				buf = forwardToNextLine(buf);
 			} else {
 				// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
 				// to the buffer, because we still need to read the new source state.
@@ -247,19 +258,16 @@ MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitio
 	// Set the locale to correctly recognize floating point numbers.
 	setlocale(LC_NUMERIC, "C");
 
-	if (!fileExistsAndIsReadable(filename.c_str())) {
+	if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
 		throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
 	}
 
-	// Determine used line endings.
-	SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
-
 	// Open file and prepare pointer to buffer.
 	MappedFile file(filename.c_str());
 	char* buf = file.data;
 
-	return secondPass(buf, lineEndings, firstPass(buf, lineEndings));
+	return secondPass(buf, firstPass(buf));
 }
 
 } // namespace parser
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index 25f9291dc..954f21a63 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -3,7 +3,6 @@
 
 #include "src/storage/SparseMatrix.h"
 #include "src/storage/BitVector.h"
-#include "Parser.h"
 
 namespace storm {
 
@@ -77,20 +76,18 @@ private:
 	 * Performs the first pass on the input pointed to by the given buffer.
 	 *
 	 * @param buffer The buffer that cointains the input.
-	 * @param lineEndings The line endings that are to be used while parsing.
 	 * @return A structure representing the result of the first pass.
 	 */
-	static FirstPassResult firstPass(char* buffer, SupportedLineEndings lineEndings);
+	static FirstPassResult firstPass(char* buffer);
 
 	/*
 	 * Performs the second pass on the input pointed to by the given buffer with the information of the first pass.
 	 *
 	 * @param buffer The buffer that cointains the input.
-	 * @param lineEndings The line endings that are to be used while parsing.
 	 * @param firstPassResult The result of the first pass performed on the same input.
 	 * @return A structure representing the result of the second pass.
 	 */
-	static ResultType secondPass(char* buffer, SupportedLineEndings lineEndings, FirstPassResult const& firstPassResult);
+	static ResultType secondPass(char* buffer, FirstPassResult const& firstPassResult);
 };
 
 } // namespace parser
diff --git a/src/parser/NondeterministicModelParser.h b/src/parser/NondeterministicModelParser.h
index 6719a4585..50a0525fb 100644
--- a/src/parser/NondeterministicModelParser.h
+++ b/src/parser/NondeterministicModelParser.h
@@ -8,7 +8,6 @@
 #ifndef STORM_PARSER_NONDETERMINISTICMODELPARSER_H_
 #define STORM_PARSER_NONDETERMINISTICMODELPARSER_H_
 
-#include "src/parser/Parser.h"
 #include "src/models/Mdp.h"
 #include "src/models/Ctmdp.h"
 
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 3c7ebbaab..6e7c72246 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -14,6 +14,8 @@
 #include "src/exceptions/FileIoException.h"
 #include "src/exceptions/WrongFormatException.h"
 
+#include "src/utility/cstring.h"
+
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;
@@ -21,6 +23,8 @@ extern log4cplus::Logger logger;
 namespace storm {
 	namespace parser {
 
+		using namespace storm::utility::cstring;
+
 		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitions(std::string const& filename) {
 
 			Result emptyResult;
@@ -38,20 +42,17 @@ namespace storm {
 			// Enforce locale where decimal point is '.'.
 			setlocale(LC_NUMERIC, "C");
 
-			if (!fileExistsAndIsReadable(filename.c_str())) {
+			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
 				throw storm::exceptions::WrongFormatException();
 			}
 
-			// Find out about the used line endings.
-			SupportedLineEndings lineEndings = findUsedLineEndings(filename, true);
-
 			// Open file.
 			MappedFile file(filename.c_str());
 			char* buf = file.data;
 
 			// Perform first pass, i.e. obtain number of columns, rows and non-zero elements.
-			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.data, lineEndings, isRewardFile, modelInformation);
+			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.data, isRewardFile, modelInformation);
 
 			// If first pass returned zero, the file format was wrong.
 			if (firstPass.numberOfNonzeroEntries == 0) {
@@ -64,7 +65,8 @@ namespace storm {
 			// Skip the format hint if it is there.
 			buf = trimWhitespaces(buf);
 			if(buf[0] < '0' || buf[0] > '9') {
-				buf = storm::parser::forwardToNextLine(buf, lineEndings);
+				buf = forwardToLineEnd(buf);
+				buf = trimWhitespaces(buf);
 			}
 
 			if (isRewardFile) {
@@ -158,7 +160,7 @@ namespace storm {
 				lastchoice = choice;
 
 				// Proceed to beginning of next line in file and next row in matrix.
-				buf = forwardToLineEnd(buf, lineEndings);
+				buf = forwardToLineEnd(buf);
 
 				buf = trimWhitespaces(buf);
 			}
@@ -172,14 +174,15 @@ namespace storm {
 			return NondeterministicSparseTransitionParser::Result(matrixBuilder.build(), rowMapping);
 		}
 
-		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, SupportedLineEndings lineEndings, bool isRewardFile, Result const & modelInformation) {
+		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, bool isRewardFile, Result const & modelInformation) {
 
 			// Check file header and extract number of transitions.
 
 			// Skip the format hint if it is there.
 			buf = trimWhitespaces(buf);
 			if(buf[0] < '0' || buf[0] > '9') {
-				buf = storm::parser::forwardToNextLine(buf, lineEndings);
+				buf = forwardToLineEnd(buf);
+				buf = trimWhitespaces(buf);
 			}
 
 			// Read all transitions.
@@ -261,7 +264,7 @@ namespace storm {
 
 				// The PRISM output format lists the name of the transition in the fourth column,
 				// but omits the fourth column if it is an internal action. In either case we can skip to the end of the line.
-				buf = forwardToLineEnd(buf, lineEndings);
+				buf = forwardToLineEnd(buf);
 
 				buf = trimWhitespaces(buf);
 			}
diff --git a/src/parser/NondeterministicSparseTransitionParser.h b/src/parser/NondeterministicSparseTransitionParser.h
index 3df4834ae..d754a39c3 100644
--- a/src/parser/NondeterministicSparseTransitionParser.h
+++ b/src/parser/NondeterministicSparseTransitionParser.h
@@ -1,7 +1,6 @@
 #ifndef STORM_PARSER_NONDETERMINISTICSPARSETRANSITIONPARSER_H_
 #define STORM_PARSER_NONDETERMINISTICSPARSETRANSITIONPARSER_H_
 
-#include "src/parser/Parser.h"
 #include "src/storage/SparseMatrix.h"
 
 #include <vector>
@@ -87,11 +86,10 @@ namespace storm {
 			 * number of columns of the matrix.
 			 *
 			 * @param buffer Buffer containing the data to scan. This is expected to be some char array.
-			 * @param lineEndings The line endings that are to be used while parsing.
 			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 			 * @return A structure representing the result of the first pass.
 			 */
-			static FirstPassResult firstPass(char* buffer, SupportedLineEndings lineEndings, bool isRewardFile, Result const & modelInformation);
+			static FirstPassResult firstPass(char* buffer, bool isRewardFile, Result const & modelInformation);
 
 			/*!
 			 * The main parsing routine.
diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp
deleted file mode 100644
index 9e4113445..000000000
--- a/src/parser/Parser.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-#include "src/parser/Parser.h"
-
-#include <fcntl.h>
-#include <iostream>
-#include <fstream>
-#include <cstring>
-#include <string>
-#include <cerrno>
-
-#include <boost/integer/integer_mask.hpp>
-#include "src/exceptions/FileIoException.h"
-#include "src/exceptions/WrongFormatException.h"
-#include "src/utility/OsDetection.h"
-#include "src/parser/MappedFile.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
-namespace storm {
-
-namespace parser {
-
-/*!
- *	Calls strtol() internally and checks if the new pointer is different
- *	from the original one, i.e. if str != *end. If they are the same, a
- *	storm::exceptions::WrongFormatException will be thrown.
- *	@param str String to parse
- *	@param end New pointer will be written there
- *	@return Result of strtol()
- */
-uint_fast64_t checked_strtol(const char* str, char** end) {
-	uint_fast64_t res = strtol(str, end, 10);
-	if (str == *end) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number.");
-		LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
-		throw storm::exceptions::WrongFormatException("Error while parsing integer. Next input token is not a number.");
-	}
-	return res;
-}
-
-/*!
- *	Calls strtod() internally and checks if the new pointer is different
- *	from the original one, i.e. if str != *end. If they are the same, a
- *	storm::exceptions::WrongFormatException will be thrown.
- *	@param str String to parse
- *	@param end New pointer will be written there
- *	@return Result of strtod()
- */
-double checked_strtod(const char* str, char** end) {
-	double res = strtod(str, end);
-	if (str == *end) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number.");
-		LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
-		throw storm::exceptions::WrongFormatException("Error while parsing floating point. Next input token is not a number.");
-	}
-	return res;
-}
-
-/*!
- *  @brief Tests whether the given file exists and is readable.
- *  @return True iff the file exists and is readable.
- */
-bool fileExistsAndIsReadable(const char* fileName) {
-	std::ifstream fin(fileName);
-	bool returnValue = !fin.fail();
-	return returnValue;
-}
-
-/*!
- * Skips all numbers, letters and special characters.
- * Returns a pointer to the first char that is a whitespace.
- * @param buf The string buffer to operate on.
- * @return A pointer to the first whitespace character.
- */
-char* skipWord(char* buf){
-	while((*buf != ' ') && (*buf != '\t') && (*buf != '\n') && (*buf != '\r')) buf++;
-	return buf;
-}
-
-/*!
- *	Skips spaces, tabs, newlines and carriage returns. Returns a pointer
- *	to first char that is not a whitespace.
- *	@param buf The string buffer to operate on.
- *	@return	A pointer to the first non-whitespace character.
- */
-char* trimWhitespaces(char* buf) {
-	while ((*buf == ' ') || (*buf == '\t') || (*buf == '\n') || (*buf == '\r')) buf++;
-	return buf;
-}
-
-/*!
- * @briefs Analyzes the given file and tries to find out the used file endings.
- */
-SupportedLineEndings findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported) {
-	MappedFile fileMap(fileName.c_str());
-	char* buf = nullptr;
-	char* const bufferEnd = fileMap.dataend;
-
-	for (buf = fileMap.data; buf != bufferEnd; ++buf) {
-		if (*buf == '\r') {
-			// check for following \n
-			if (((buf + sizeof(char)) < bufferEnd) && (*(buf + sizeof(char)) == '\n')) {
-				return SupportedLineEndings::SlashRN;
-			}
-			return SupportedLineEndings::SlashR;
-		} else if (*buf == '\n') {
-			return SupportedLineEndings::SlashN;
-		}
-	}
-
-	if (throwOnUnsupported) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n");
-		throw storm::exceptions::WrongFormatException() << "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n";
-	}
-	LOG4CPLUS_WARN(logger, "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n");
-
-	return SupportedLineEndings::Unsupported;
-}
-
-/*!
- * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
- */
-char* forwardToLineEnd(char* buffer, SupportedLineEndings lineEndings) {
-	switch (lineEndings) {
-		case SupportedLineEndings::SlashN:
-			return buffer + strcspn(buffer, "\n\0");
-			break;
-		case SupportedLineEndings::SlashR:
-			return buffer + strcspn(buffer, "\r\0");
-			break;
-		case SupportedLineEndings::SlashRN:
-			return buffer + strcspn(buffer, "\r\0");
-			break;
-		default:
-		case SupportedLineEndings::Unsupported:
-			// This Line will never be reached as the Parser would have thrown already.
-			throw;
-			break;
-	}
-	return nullptr;
-}
-
-/*!
- * @brief Encapsulates the usage of function @strchr to forward to the next line
- */
-char* forwardToNextLine(char* buffer, SupportedLineEndings lineEndings) {
-	switch (lineEndings) {
-		case SupportedLineEndings::SlashN:
-			return strchr(buffer, '\n') + 1;  
-			break;
-		case SupportedLineEndings::SlashR:
-			return strchr(buffer, '\r') + 1;  
-			break;
-		case SupportedLineEndings::SlashRN:
-			return strchr(buffer, '\r') + 2;
-			break;
-		default:
-		case SupportedLineEndings::Unsupported:
-			// This Line will never be reached as the Parser would have thrown already.
-			throw;
-			break;
-	}
-	return nullptr;
-}
-
-/*!
- * @brief Encapsulates the usage of function @sscanf to scan for the model type hint
- * @param targetBuffer The Target for the hint, must be at least 64 bytes long
- * @param buffer The Source Buffer from which the Model Hint will be read
- */
-void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, SupportedLineEndings lineEndings) {
-	if (targetBufferSize <= 4) {
-		throw;
-	}
-	switch (lineEndings) {
-		case SupportedLineEndings::SlashN:
-#ifdef WINDOWS					
-			sscanf_s(buffer, "%60s\n", targetBuffer, targetBufferSize);
-#else
-			sscanf(buffer, "%60s\n", targetBuffer);
-#endif
-			break;
-		case SupportedLineEndings::SlashR:
-#ifdef WINDOWS					
-			sscanf_s(buffer, "%60s\r", targetBuffer, sizeof(targetBufferSize));
-#else
-			sscanf(buffer, "%60s\r", targetBuffer);
-#endif
-			break;
-		case SupportedLineEndings::SlashRN:
-#ifdef WINDOWS					
-			sscanf_s(buffer, "%60s\r\n", targetBuffer, sizeof(targetBufferSize));
-#else
-			sscanf(buffer, "%60s\r\n", targetBuffer);
-#endif
-			break;
-		default:
-		case SupportedLineEndings::Unsupported:
-			// This Line will never be reached as the Parser would have thrown already.
-			throw;
-			break;
-	}
-}
-
-/*!
- * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
- */
-void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, SupportedLineEndings lineEndings) {
-	if (targetBufferSize < 5) {
-		LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed Target Buffer is too small.");
-		throw;
-	}
-	switch (lineEndings) {
-		case SupportedLineEndings::SlashN: {
-			char source[] = " \n\t";
-#ifdef WINDOWS			
-			strncpy(targetBuffer, targetBufferSize, source, sizeof(source));
-#else
-			strncpy(targetBuffer, source, targetBufferSize);
-#endif
-			break;
-											   }
-		case SupportedLineEndings::SlashR: {
-			char source[] = " \r\t";
-#ifdef WINDOWS			
-			strncpy(targetBuffer, targetBufferSize, source, sizeof(source));
-#else
-			strncpy(targetBuffer, source, targetBufferSize);
-#endif
-			break;
-											   }
-		case SupportedLineEndings::SlashRN: {
-			char source[] = " \r\n\t";
-#ifdef WINDOWS			
-			strncpy(targetBuffer, targetBufferSize, source, sizeof(source));
-#else
-			strncpy(targetBuffer, source, targetBufferSize);
-#endif
-			break;
-												}
-		default:
-		case SupportedLineEndings::Unsupported:
-			// This Line will never be reached as the Parser would have thrown already.
-			LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed lineEndings were Unsupported. Check your input file.");
-			throw;
-			break;
-	}
-}
-
-} // namespace parser
-
-} // namespace storm
diff --git a/src/parser/Parser.h b/src/parser/Parser.h
deleted file mode 100644
index 962f699eb..000000000
--- a/src/parser/Parser.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Parser.h
- *
- *  Created on: 21.11.2012
- *      Author: Gereon Kremer
- */
-
-#ifndef STORM_PARSER_PARSER_H_
-#define STORM_PARSER_PARSER_H_
-
-#include "src/utility/OsDetection.h"
-
-#include <sys/stat.h>
-#include <vector>
-#include <string>
-
-namespace storm {
-
-	/*!
-	 *	@brief Contains all file parsers and helper classes.
-	 *
-	 *	This namespace contains everything needed to load data files (like
-	 *	atomic propositions, transition systems, formulas, etc.) including
-	 *	methods for efficient file access (see MappedFile).
-	 */
-	namespace parser {
-
-	/*!
-	 *	@brief Parses integer and checks, if something has been parsed.
-	 */
-	uint_fast64_t checked_strtol(const char* str, char** end);
-
-	/*!
-	 *	@brief Parses floating point and checks, if something has been parsed.
-	 */
-	double checked_strtod(const char* str, char** end);
-
-	/*!
-	 * @brief Skips all non whitespace characters until the next whitespace.
-	 */
-	char* skipWord(char* buf);
-
-	/*!
-	 *	@brief Skips common whitespaces in a string.
-	 */
-	char* trimWhitespaces(char* buf);
-
-	/*!
-	 *  @brief Tests whether the given file exists and is readable.
-	 */
-	bool fileExistsAndIsReadable(const char* fileName);
-
-	/*!
-	 * @brief Enum Class Type containing all supported file endings.
-	 */
-	enum class SupportedLineEndings : unsigned short {
-		Unsupported = 0,
-		SlashR,
-		SlashN,
-		SlashRN
-	};
-
-	/*!
-	 * @briefs Analyzes the given file and tries to find out the used line endings.
-	 */
-	storm::parser::SupportedLineEndings findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false);
-
-	/*!
-	 * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
-	 */
-	char* forwardToLineEnd(char* buffer, storm::parser::SupportedLineEndings lineEndings);
-
-	/*!
-	 * @brief Encapsulates the usage of function @strchr to forward to the next line
-	 */
-	char* forwardToNextLine(char* buffer, storm::parser::SupportedLineEndings lineEndings);
-
-	/*!
-	 * @brief Encapsulates the usage of function @sscanf to scan for the model type hint
-	 * @param targetBuffer The Target for the hint, should be at least 64 bytes long
-	 * @param buffer The Source Buffer from which the Model Hint will be read
-	 */
-	void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndings lineEndings);
-	
-	/*!
-	 * @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0
-	 */
-	void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndings lineEndings);
-
-	} // namespace parser
-} // namespace storm
-
-#endif /* STORM_PARSER_PARSER_H_ */
diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h
index 848d1de99..3ba8f1998 100644
--- a/src/parser/PrctlParser.h
+++ b/src/parser/PrctlParser.h
@@ -1,8 +1,6 @@
 #ifndef STORM_PARSER_PRCTLPARSER_H_
 #define STORM_PARSER_PRCTLPARSER_H_
 
-#include "src/parser/Parser.h"
-
 #include "src/formula/Prctl.h"
 //#include <memory>
 
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index a0bd62ce3..c79e6f691 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -11,7 +11,7 @@
 
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
-#include "src/parser/Parser.h"
+#include "src/utility/cstring.h"
 #include "src/parser/MappedFile.h"
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
@@ -21,6 +21,8 @@ namespace storm {
 
 namespace parser {
 
+using namespace storm::utility::cstring;
+
 /*!
  *	Reads a state reward file and puts the result in a state reward vector.
  *
@@ -30,7 +32,7 @@ namespace parser {
  */
 std::vector<double> SparseStateRewardParser::parseSparseStateReward(uint_fast64_t stateCount, std::string const & filename) {
 	// Open file.
-	if (!fileExistsAndIsReadable(filename.c_str())) {
+	if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
 		throw storm::exceptions::WrongFormatException();
 	}
diff --git a/src/utility/cstring.cpp b/src/utility/cstring.cpp
new file mode 100644
index 000000000..2267fdf62
--- /dev/null
+++ b/src/utility/cstring.cpp
@@ -0,0 +1,95 @@
+#include "src/utility/cstring.h"
+
+#include <cstring>
+
+#include "src/exceptions/WrongFormatException.h"
+
+#include "log4cplus/logger.h"
+#include "log4cplus/loggingmacros.h"
+extern log4cplus::Logger logger;
+
+namespace storm {
+
+namespace utility {
+
+namespace cstring {
+
+/*!
+ *	Calls strtol() internally and checks if the new pointer is different
+ *	from the original one, i.e. if str != *end. If they are the same, a
+ *	storm::exceptions::WrongFormatException will be thrown.
+ *	@param str String to parse
+ *	@param end New pointer will be written there
+ *	@return Result of strtol()
+ */
+uint_fast64_t checked_strtol(const char* str, char** end) {
+	uint_fast64_t res = strtol(str, end, 10);
+	if (str == *end) {
+		LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number.");
+		LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
+		throw storm::exceptions::WrongFormatException("Error while parsing integer. Next input token is not a number.");
+	}
+	return res;
+}
+
+/*!
+ *	Calls strtod() internally and checks if the new pointer is different
+ *	from the original one, i.e. if str != *end. If they are the same, a
+ *	storm::exceptions::WrongFormatException will be thrown.
+ *	@param str String to parse
+ *	@param end New pointer will be written there
+ *	@return Result of strtod()
+ */
+double checked_strtod(const char* str, char** end) {
+	double res = strtod(str, end);
+	if (str == *end) {
+		LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number.");
+		LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
+		throw storm::exceptions::WrongFormatException("Error while parsing floating point. Next input token is not a number.");
+	}
+	return res;
+}
+
+/*!
+ * Skips all numbers, letters and special characters.
+ * Returns a pointer to the first char that is a whitespace.
+ * @param buf The string buffer to operate on.
+ * @return A pointer to the first whitespace character.
+ */
+char* skipWord(char* buf){
+	while(!isspace(*buf) && *buf != '\0') buf++;
+	return buf;
+}
+
+/*!
+ *	Skips spaces, tabs, newlines and carriage returns. Returns a pointer
+ *	to first char that is not a whitespace.
+ *	@param buf The string buffer to operate on.
+ *	@return	A pointer to the first non-whitespace character.
+ */
+char* trimWhitespaces(char* buf) {
+	while (isspace(*buf)) buf++;
+	return buf;
+}
+
+/*!
+ * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
+ */
+char* forwardToLineEnd(char* buffer) {
+	return buffer + strcspn(buffer, "\n\r\0");
+}
+
+/*!
+ * @brief Encapsulates the usage of function @strchr to forward to the next line
+ */
+char* forwardToNextLine(char* buffer) {
+	char* lineEnd = forwardToLineEnd(buffer);
+	while((*lineEnd == '\n') || (*lineEnd == '\r')) lineEnd++;
+	return lineEnd;
+}
+
+} // namespace cstring
+
+} // namespace utility
+
+} // namespace storm
diff --git a/src/utility/cstring.h b/src/utility/cstring.h
new file mode 100644
index 000000000..ebe153f3b
--- /dev/null
+++ b/src/utility/cstring.h
@@ -0,0 +1,53 @@
+/*
+ * cstring.h
+ *
+ *  Created on: 30.01.2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#ifndef STORM_UTILITY_CSTRING_H_
+#define STORM_UTILITY_CSTRING_H_
+
+#include <cstdint>
+
+namespace storm {
+	namespace utility {
+		namespace cstring {
+
+		/*!
+		 *	@brief Parses integer and checks, if something has been parsed.
+		 */
+		uint_fast64_t checked_strtol(const char* str, char** end);
+
+		/*!
+		 *	@brief Parses floating point and checks, if something has been parsed.
+		 */
+		double checked_strtod(const char* str, char** end);
+
+		/*!
+		 * @brief Skips all non whitespace characters until the next whitespace.
+		 */
+		char* skipWord(char* buf);
+
+		/*!
+		 *	@brief Skips common whitespaces in a string.
+		 */
+		char* trimWhitespaces(char* buf);
+
+		/*!
+		 * @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character).
+		 */
+		char* forwardToLineEnd(char* buffer);
+
+		/*!
+		 * @brief Encapsulates the usage of function @strchr to forward to the next line
+		 *
+		 * Note: All lines after the current, which do not contain any characters are skipped.
+		 */
+		char* forwardToNextLine(char* buffer);
+
+		} // namespace cstring
+	} // namespace utility
+} // namespace storm
+
+#endif /* STORM_UTILITY_CSTRING_H_ */
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index d4ad69b75..77af61ef7 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -14,7 +14,7 @@
 
 #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
 #include "src/parser/SparseStateRewardParser.h"
-#include "src/parser/Parser.h"
+#include "src/utility/cstring.h"
 #include "src/parser/MarkovAutomatonParser.h"
 
 #define STATE_COUNT 6

From 52f130ea5c99b4be0d3e731203c76c097e1b5439 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Fri, 7 Feb 2014 21:19:50 +0100
Subject: [PATCH 014/147] Commenting and cleanup.

-Also threw out a few more unneeded includes.

Next up: Tests and then remerge.


Former-commit-id: 79f35c440988e0d279055c89cb9cab097aad0e3f
---
 .../AtomicPropositionLabelingParser.cpp       |   8 +-
 src/parser/AtomicPropositionLabelingParser.h  |  17 +-
 src/parser/AutoParser.cpp                     |  29 +-
 src/parser/AutoParser.h                       |  44 +-
 src/parser/DeterministicModelParser.cpp       |  76 ++-
 src/parser/DeterministicModelParser.h         | 189 +++++---
 .../DeterministicSparseTransitionParser.cpp   |   4 +-
 .../DeterministicSparseTransitionParser.h     | 157 ++++---
 src/parser/MappedFile.cpp                     |  35 +-
 src/parser/MappedFile.h                       |  86 ++--
 src/parser/MarkovAutomatonParser.cpp          |  48 +-
 src/parser/MarkovAutomatonParser.h            |  49 +-
 .../MarkovAutomatonSparseTransitionParser.cpp | 435 +++++++++---------
 .../MarkovAutomatonSparseTransitionParser.h   | 181 ++++----
 src/parser/NondeterministicModelParser.cpp    |  42 +-
 src/parser/NondeterministicModelParser.h      |  87 +++-
 ...NondeterministicSparseTransitionParser.cpp |   4 +-
 .../NondeterministicSparseTransitionParser.h  |  53 ++-
 src/parser/SparseStateRewardParser.cpp        |  86 ++--
 src/parser/SparseStateRewardParser.h          |  38 +-
 .../parser/MarkovAutomatonParserTest.cpp      |   4 +-
 21 files changed, 893 insertions(+), 779 deletions(-)

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index ad5543476..f56cbb025 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -25,7 +25,7 @@ namespace storm {
 
 		using namespace storm::utility::cstring;
 
-		storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const & filename) {
+		storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const & filename) {
 
 			// Open the given file.
 			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
@@ -34,7 +34,7 @@ namespace storm {
 			}
 
 			MappedFile file(filename.c_str());
-			char* buf = file.data;
+			char* buf = file.getData();
 
 			// First pass: Count the number of propositions.
 			bool foundDecl = false, foundEnd = false;
@@ -76,11 +76,11 @@ namespace storm {
 
 
 			// Create labeling object with given node and proposition count.
-			storm::models::AtomicPropositionsLabeling labeling(node_count, proposition_count);
+			storm::models::AtomicPropositionsLabeling labeling(stateCount, proposition_count);
 
 			// Second pass: Add propositions and node labels to labeling.
 			// First thing to do: Reset the file pointer.
-			buf = file.data;
+			buf = file.getData();
 
 			// Prepare a buffer for proposition names.
 			char proposition[128];
diff --git a/src/parser/AtomicPropositionLabelingParser.h b/src/parser/AtomicPropositionLabelingParser.h
index 976dd9f35..19d172235 100644
--- a/src/parser/AtomicPropositionLabelingParser.h
+++ b/src/parser/AtomicPropositionLabelingParser.h
@@ -7,18 +7,23 @@
 namespace storm {
 	namespace parser {
 
+		/*!
+		 * This class can be used to parse a labeling file.
+		 *
+		 * Since the labeling is state based, the same label parser can be used for all models.
+		 */
 		class AtomicPropositionLabelingParser {
 
 		public:
 
-			/*
-			 *	Reads a label file and puts the result in an AtomicPropositionsLabeling object.
+			/*!
+			 * Reads a label file and puts the result in an AtomicPropositionsLabeling object.
 			 *
-			 *	@param node_count The number of states of the model to be labeled.
-			 *	@param filename The path and name of the labeling (.lab) file.
-			 *	@return The parsed labeling as an AtomicPropositionsLabeling object.
+			 * @param stateCount The number of states of the model to be labeled.
+			 * @param filename The path and name of the labeling (.lab) file.
+			 * @return The parsed labeling as an AtomicPropositionsLabeling object.
 			 */
-			static storm::models::AtomicPropositionsLabeling parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const &filename);
+			static storm::models::AtomicPropositionsLabeling parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const &filename);
 
 		};
 
diff --git a/src/parser/AutoParser.cpp b/src/parser/AutoParser.cpp
index d9d6bcfa5..808d36f0b 100644
--- a/src/parser/AutoParser.cpp
+++ b/src/parser/AutoParser.cpp
@@ -22,19 +22,19 @@ namespace storm {
 
 		using namespace storm::utility::cstring;
 
-		std::shared_ptr<storm::models::AbstractModel<double>> AutoParser::parseModel(std::string const & transitionSystemFile,
-																					 std::string const & labelingFile,
-																					 std::string const & stateRewardFile,
-																					 std::string const & transitionRewardFile) {
+		std::shared_ptr<storm::models::AbstractModel<double>> AutoParser::parseModel(std::string const & transitionsFilename,
+																					 std::string const & labelingFilename,
+																					 std::string const & stateRewardFilename,
+																					 std::string const & transitionRewardFilename) {
 
 			// Find and parse the model type hint.
-			storm::models::ModelType type = AutoParser::analyzeHint(transitionSystemFile);
+			storm::models::ModelType type = AutoParser::analyzeHint(transitionsFilename);
 
 			// In case the hint string is unknown or could not be found, throw an exception.
 			if (type == storm::models::Unknown) {
-				LOG4CPLUS_ERROR(logger, "Could not determine file type of " << transitionSystemFile << ".");
+				LOG4CPLUS_ERROR(logger, "Could not determine file type of " << transitionsFilename << ".");
 				LOG4CPLUS_ERROR(logger, "The first line of the file should contain a format hint. Please fix your file and try again.");
-				throw storm::exceptions::WrongFormatException() << "Could not determine type of file " << transitionSystemFile;
+				throw storm::exceptions::WrongFormatException() << "Could not determine type of file " << transitionsFilename;
 			} else {
 				LOG4CPLUS_INFO(logger, "Model type seems to be " << type);
 			}
@@ -43,23 +43,23 @@ namespace storm {
 			std::shared_ptr<storm::models::AbstractModel<double>> model;
 			switch (type) {
 				case storm::models::DTMC: {
-					model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParser::parseDtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParser::parseDtmc(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
 					break;
 				}
 				case storm::models::CTMC: {
-					model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParser::parseCtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParser::parseCtmc(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
 					break;
 				}
 				case storm::models::MDP: {
-					model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParser::parseMdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParser::parseMdp(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
 					break;
 				}
 				case storm::models::CTMDP: {
-					model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParser::parseCtmdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
+					model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParser::parseCtmdp(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
 					break;
 				}
 				case storm::models::MA: {
-					model.reset(new storm::models::MarkovAutomaton<double>(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
+					model.reset(new storm::models::MarkovAutomaton<double>(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename)));
 					break;
 				}
 				default:
@@ -69,12 +69,12 @@ namespace storm {
 			return model;
 		}
 
-		storm::models::ModelType AutoParser::analyzeHint(const std::string& filename) {
+		storm::models::ModelType AutoParser::analyzeHint(std::string const & filename) {
 			storm::models::ModelType hintType = storm::models::Unknown;
 
 			// Open the file.
 			MappedFile file(filename.c_str());
-			char* buf = file.data;
+			char* buf = file.getData();
 
 			// Find and read in the hint.
 			char hint[65];
@@ -96,5 +96,6 @@ namespace storm {
 
 			return hintType;
 		}
+
 	} // namespace parser
 } // namespace storm
diff --git a/src/parser/AutoParser.h b/src/parser/AutoParser.h
index 88df0d076..993cbe6bb 100644
--- a/src/parser/AutoParser.h
+++ b/src/parser/AutoParser.h
@@ -8,37 +8,43 @@
 namespace storm {
 
 	/*!
-	 *	@brief Contains all file parsers and helper classes.
+	 * Contains all file parsers and helper classes.
 	 *
-	 *	This namespace contains everything needed to load data files (like
-	 *	atomic propositions, transition systems, formulas, etc.) including
-	 *	methods for efficient file access (see MappedFile).
+	 * This namespace contains everything needed to load data files (like
+	 * atomic propositions, transition systems, formulas, etc.) including
+	 * methods for efficient file access (see MappedFile).
 	 */
 	namespace parser {
 
+		/*!
+		 * This class automatically chooses the correct parser for the given files and returns the corresponding model.
+		 * The choice of the parser is made using the model hint at the beginning of the given transition file.
+		 */
 		class AutoParser {
 		public:
 
 			/*!
-			 *	Checks the given files and parses the model within these files.
+			 * Checks the given files and parses the model within these files.
 			 *
-			 *	This parser analyzes the format hint in the first line of the transition
-			 *	file. If this is a valid format, it will use the parser for this format,
-			 *	otherwise it will throw an exception.
+			 * This parser analyzes the format hint in the first line of the transition file.
+			 * If this is a valid format, it will use the parser for this format, otherwise it will throw an exception.
 			 *
-			 *	When the files are parsed successfully, a shared pointer owning the resulting model is returned.
-			 *	The concrete model can be obtained using the as<Type>() member of the AbstractModel class.
+			 * When the files are parsed successfully, a shared pointer owning the resulting model is returned.
+			 * The concrete model can be obtained using the as<Type>() member of the AbstractModel class.
 			 *
-			 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
-			 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
-			 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
-			 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton.
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file that contains the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file that contains the transition rewards of the model. This file is optional.
 			 * @return A shared_ptr containing the resulting model.
 			 */
-			static std::shared_ptr<storm::models::AbstractModel<double>> parseModel(std::string const & transitionSystemFile,
-																   std::string const & labelingFile,
-																   std::string const & stateRewardFile = "",
-																   std::string const & transitionRewardFile = "");
+			static std::shared_ptr<storm::models::AbstractModel<double>> parseModel(std::string const & transitionsFilename,
+                                                                                    std::string const & labelingFilename,
+                                                                                    std::string const & stateRewardFilename = "",
+                                                                                    std::string const & transitionRewardFilename = "");
 
 		private:
 
@@ -48,7 +54,7 @@ namespace storm {
 			 *	@param filename The path and name of the file that is to be analysed.
 			 *	@return The type of the model as an enum value.
 			 */
-			static storm::models::ModelType analyzeHint(const std::string& filename);
+			static storm::models::ModelType analyzeHint(std::string const & filename);
 		};
 		
 	} // namespace parser
diff --git a/src/parser/DeterministicModelParser.cpp b/src/parser/DeterministicModelParser.cpp
index 48b613644..379858b24 100644
--- a/src/parser/DeterministicModelParser.cpp
+++ b/src/parser/DeterministicModelParser.cpp
@@ -15,65 +15,45 @@
 #include "src/parser/SparseStateRewardParser.h"
 
 namespace storm {
-namespace parser {
+	namespace parser {
 
-/*!
- * Parses a transition file and a labeling file
- * Note that the labeling file may have at most as many nodes as the transition file!
- *
- * @param transitionSystemFile String containing the location of the transition file (....tra)
- * @param labelingFile String containing the location of the labeling file (....lab)
- * @param stateRewardFile String containing the location of the state reward file (...srew)
- * @param transitionRewardFile String containing the location of the transition reward file (...trew)
- */
-DeterministicModelParser::Result DeterministicModelParser::parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+		DeterministicModelParser::Result DeterministicModelParser::parseDeterministicModel(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
-	// Parse the transitions.
-	storm::storage::SparseMatrix<double> transitions(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionSystemFile)));
+			// Parse the transitions.
+			storm::storage::SparseMatrix<double> transitions(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionsFilename)));
 
-	uint_fast64_t stateCount = transitions.getColumnCount();
+			uint_fast64_t stateCount = transitions.getColumnCount();
 
-	// Parse the state labeling.
-	storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
+			// Parse the state labeling.
+			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFilename)));
 
-	// Construct the result.
-	DeterministicModelParser::Result result(std::move(transitions), std::move(labeling));
+			// Construct the result.
+			DeterministicModelParser::Result result(std::move(transitions), std::move(labeling));
 
-	// Only parse state rewards if a file is given.
-	if (stateRewardFile != "") {
-		result.stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile);
-	}
+			// Only parse state rewards if a file is given.
+			if (stateRewardFilename != "") {
+				result.stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFilename);
+			}
 
-	// Only parse transition rewards if a file is given.
-	if (transitionRewardFile != "") {
-		result.transitionRewards = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFile, result.transitionSystem);
-	}
+			// Only parse transition rewards if a file is given.
+			if (transitionRewardFilename != "") {
+				result.transitionRewards = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFilename, result.transitionSystem);
+			}
 
-	return result;
-}
+			return result;
+		}
 
-/*!
- * Uses the parseDeterministicModel function internally to parse the given input files.
- * @note This is a short-hand for constructing a Dtmc directly from the data returned by @parseDeterministicModel
- * @return A Dtmc Model
- */
-storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+		storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
-	DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
-	return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
-}
-
-/*!
- * Uses the parseDeterministicModel function internally to parse the given input files.
- * @note This is a short-hand for constructing a Ctmc directly from the data returned by @parseDeterministicModel
- * @return A Ctmc Model
- */
-storm::models::Ctmc<double> DeterministicModelParser::parseCtmc(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+			DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename)));
+			return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+		}
 
-	DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
-	return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
-}
+		storm::models::Ctmc<double> DeterministicModelParser::parseCtmc(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
-} /* namespace parser */
+			DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename)));
+			return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+		}
 
+	} /* namespace parser */
 } /* namespace storm */
diff --git a/src/parser/DeterministicModelParser.h b/src/parser/DeterministicModelParser.h
index 2143ea820..12aba0470 100644
--- a/src/parser/DeterministicModelParser.h
+++ b/src/parser/DeterministicModelParser.h
@@ -11,83 +11,120 @@
 #include "src/models/Dtmc.h"
 #include "src/models/Ctmc.h"
 
-#include <boost/optional.hpp>
-
 namespace storm {
-namespace parser {
-
-/*!
- *	@brief Loads a deterministic model (Dtmc or Ctmc) from files.
- *
- *	Given the file paths of the files holding the transitions, the atomic propositions and optionally the state- and transition rewards
- *	it loads the files, parses them and returns the desired model.
- *
- *	@note This class creates a new Dtmc or Ctmc object
- *
- *	@note The labeling representation in the file may use at most as much nodes as are specified in the transition system.
- */
-
-class DeterministicModelParser {
-
-public:
-
-	/*!
-	 * @brief A struct containing the parsed components of a deterministic model.
-	 */
-	struct Result {
-
-		Result(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
-			// Intentionally left empty.
-		}
-
-		Result(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
-			// Intentionally left empty.
-		}
-
-		// A matrix representing the transitions of the model
-		storm::storage::SparseMatrix<double> transitionSystem;
-
-		// The labels of each state.
-		storm::models::AtomicPropositionsLabeling labeling;
-
-		// Optional rewards for each state.
-		boost::optional<std::vector<double>> stateRewards;
-
-		// Optional rewards for each transition.
-		boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
-	};
-
-
-	/*!
-	 * @brief Parse a Dtmc.
-	 */
-	static storm::models::Dtmc<double> parseDtmc(std::string const & transitionSystemFile,
-												 std::string const & labelingFile,
-												 std::string const & stateRewardFile = "",
-												 std::string const & transitionRewardFile = "");
-
-	/*!
-	 * @brief Parse a Ctmc.
-	 */
-	static storm::models::Ctmc<double> parseCtmc(std::string const & transitionSystemFile,
-										  	     std::string const & labelingFile,
-										  	     std::string const & stateRewardFile = "",
-										  	     std::string const & transitionRewardFile = "");
-
-private:
-
-	/*!
-	 * @brief Call sub-parsers on the given files and fill the container with the results.
-	 */
-	static Result parseDeterministicModel(std::string const & transitionSystemFile,
-												   std::string const & labelingFile,
-												   std::string const & stateRewardFile = "",
-												   std::string const & transitionRewardFile = "");
-
-};
-
-} /* namespace parser */
-
+	namespace parser {
+
+		/*!
+		 * Loads a deterministic model (Dtmc or Ctmc) from files.
+		 *
+		 * Given the file paths of the files holding the transitions, the atomic propositions and optionally the state- and transition rewards
+		 * it loads the files, parses them and returns the desired model.
+		 */
+		class DeterministicModelParser {
+
+		public:
+
+			/*!
+			 * A structure containing the parsed components of a deterministic model.
+			 */
+			struct Result {
+
+				/*!
+				 * The copy constructor.
+				 *
+				 * @param transitionSystem The transition system to be contained in the Result.
+				 * @param labeling The the labeling of the transition system to be contained in the Result.
+				 */
+				Result(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
+					// Intentionally left empty.
+				}
+
+				/*!
+				 * The move constructor.
+				 *
+				 * @param transitionSystem The transition system to be contained in the Result.
+				 * @param labeling The the labeling of the transition system to be contained in the Result.
+				 */
+				Result(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
+					// Intentionally left empty.
+				}
+
+				//! A matrix representing the transitions of the model
+				storm::storage::SparseMatrix<double> transitionSystem;
+
+				//! The labels of each state.
+				storm::models::AtomicPropositionsLabeling labeling;
+
+				//! Optional rewards for each state.
+				boost::optional<std::vector<double>> stateRewards;
+
+				//! Optional rewards for each transition.
+				boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
+			};
+
+
+			/*!
+			 * Parse a Dtmc.
+			 *
+			 * This method is an adapter to the actual parsing function.
+			 * I.e. it uses @parseDeterministicModel internally to parse the given input files, takes its result and compiles it into a Dtmc.
+			 *
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
+			 * @return The parsed Dtmc.
+			 */
+			static storm::models::Dtmc<double> parseDtmc(std::string const & transitionsFilename,
+														 std::string const & labelingFilename,
+														 std::string const & stateRewardFilename = "",
+														 std::string const & transitionRewardFilename = "");
+
+			/*!
+			 * Parse a Ctmc.
+			 *
+			 * This method is an adapter to the actual parsing function.
+			 * I.e. it uses @parseDeterministicModel internally to parse the given input files, takes its result and compiles it into a Ctmc.
+			 *
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
+			 * @return The parsed Ctmc.
+			 */
+			static storm::models::Ctmc<double> parseCtmc(std::string const & transitionsFilename,
+														 std::string const & labelingFilename,
+														 std::string const & stateRewardFilename = "",
+														 std::string const & transitionRewardFilename = "");
+
+		private:
+
+			/*!
+			 * Parses a deterministic model from the given files.
+			 * Calls sub-parsers on the given files and fills the container with the results.
+			 *
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
+			 * @return The parsed model encapsulated in a Result structure.
+			 */
+			static Result parseDeterministicModel(std::string const & transitionsFilename,
+												  std::string const & labelingFilename,
+												  std::string const & stateRewardFilename = "",
+												  std::string const & transitionRewardFilename = "");
+		};
+
+	} /* namespace parser */
 } /* namespace storm */
 
 #endif /* STORM_PARSER_DETERMINISTICMODELPARSER_H_ */
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index a127ebde0..883908a53 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -53,11 +53,11 @@ namespace storm {
 
 				// Open file.
 				MappedFile file(filename.c_str());
-				char* buf = file.data;
+				char* buf = file.getData();
 
 				// Perform first pass, i.e. count entries that are not zero.
 				bool insertDiagonalEntriesIfMissing = !isRewardFile;
-				DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.data, insertDiagonalEntriesIfMissing);
+				DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.getData(), insertDiagonalEntriesIfMissing);
 
 				LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
 
diff --git a/src/parser/DeterministicSparseTransitionParser.h b/src/parser/DeterministicSparseTransitionParser.h
index d89490bee..e31ef2291 100644
--- a/src/parser/DeterministicSparseTransitionParser.h
+++ b/src/parser/DeterministicSparseTransitionParser.h
@@ -4,82 +4,87 @@
 #include "src/storage/SparseMatrix.h"
 
 namespace storm {
-
-namespace parser {
-
-class DeterministicSparseTransitionParser {
-public:
-	/*
-	 * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model and the highest state index.
-	 */
-	struct FirstPassResult {
-
-		FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0) {
-			// Intentionally left empty.
-		}
-
-		// The total number of non-zero entries of the model.
-		uint_fast64_t numberOfNonzeroEntries;
-
-		// The highest state index that appears in the model.
-		uint_fast64_t highestStateIndex;
-	};
-
-	/*!
-	 * Load a deterministic transition system from file and create a
-	 * sparse adjacency matrix whose entries represent the weights of the edges.
-	 *
-	 * @param filename The path of file to be parsed.
-	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
-	 * @return A SparseMatrix containing the parsed transition system.
-	 */
-	static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename);
-
-	/*!
-	 * Load the transition rewards for a deterministic transition system from file and create a
-	 * sparse adjacency matrix whose entries represent the rewards of the respective transitions.
-	 */
-
-	/*!
-	 * Load the transition rewards for a deterministic transition system from file and create a
-	 * sparse adjacency matrix whose entries represent the rewards of the respective transitions.
-	 *
-	 * @param filename The path of file to be parsed.
-	 * @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
-	 *                         The dimensions (rows and columns) of the two matrices should match.
-	 * @return A SparseMatrix containing the parsed transition rewards.
-	 */
-	static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & transitionMatrix);
-
-private:
-
-	/*
-	 * Performs the first pass on the input pointed to by the given buffer to obtain the number of
-	 * transitions and the maximum node id.
-	 *
-	 * @param buffer The buffer that cointains the input.
-	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
-	 * @return A structure representing the result of the first pass.
-	 */
-	static FirstPassResult firstPass(char* buffer, bool insertDiagonalEntriesIfMissing = true);
-
-	/*
-	 * The main parsing routine.
-	 * Opens the given file, calls the first pass and performs the second pass, parsing the content of the file into a SparseMatrix.
-	 *
-	 * @param filename The path of file to be parsed.
-	 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
-	 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
-	 * @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
-	 *                         The dimensions (rows and columns) of the two matrices should match.
-	 * @return A SparseMatrix containing the parsed file contents.
-	 */
-	static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & transitionMatrix);
-
-};
-
-} // namespace parser
-
+	namespace parser {
+
+		/*!
+		 *	This class can be used to parse a file containing either transitions or transition rewards of a deterministic model.
+		 *
+		 *	The file is parsed in two passes.
+		 *	The first pass tests the file format and collects statistical data needed for the second pass.
+		 *	The second pass then parses the file data and constructs a SparseMatrix representing it.
+		 */
+		class DeterministicSparseTransitionParser {
+		public:
+
+			/*!
+			 * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model and the highest state index.
+			 */
+			struct FirstPassResult {
+
+				/*!
+				 * The default constructor.
+				 * Constructs an empty FirstPassResult.
+				 */
+				FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0) {
+					// Intentionally left empty.
+				}
+
+				//! The total number of non-zero entries of the model.
+				uint_fast64_t numberOfNonzeroEntries;
+
+				//! The highest state index that appears in the model.
+				uint_fast64_t highestStateIndex;
+			};
+
+			/*!
+			 * Load a deterministic transition system from file and create a
+			 * sparse adjacency matrix whose entries represent the weights of the edges.
+			 *
+			 * @param filename The path and name of the file to be parsed.
+			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+			 * @return A SparseMatrix containing the parsed transition system.
+			 */
+			static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename);
+
+			/*!
+			 * Load the transition rewards for a deterministic transition system from file and create a
+			 * sparse adjacency matrix whose entries represent the rewards of the respective transitions.
+			 *
+			 * @param filename The path and name of the file to be parsed.
+			 * @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
+			 *                         The dimensions (rows and columns) of the two matrices should match.
+			 * @return A SparseMatrix containing the parsed transition rewards.
+			 */
+			static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & transitionMatrix);
+
+		private:
+
+			/*
+			 * Performs the first pass on the input pointed to by the given buffer to obtain the number of
+			 * transitions and the maximum node id.
+			 *
+			 * @param buffer The buffer that contains the input.
+			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+			 * @return A structure representing the result of the first pass.
+			 */
+			static FirstPassResult firstPass(char* buffer, bool insertDiagonalEntriesIfMissing = true);
+
+			/*
+			 * The main parsing routine.
+			 * Opens the given file, calls the first pass and performs the second pass, parsing the content of the file into a SparseMatrix.
+			 *
+			 * @param filename The path and name of the file to be parsed.
+			 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
+			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
+			 * @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
+			 *                         The dimensions (rows and columns) of the two matrices should match.
+			 * @return A SparseMatrix containing the parsed file contents.
+			 */
+			static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & transitionMatrix);
+
+		};
+
+	} // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_ */
diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp
index c1c654aa7..2b7e13a05 100644
--- a/src/parser/MappedFile.cpp
+++ b/src/parser/MappedFile.cpp
@@ -24,10 +24,10 @@ namespace storm {
 
 		MappedFile::MappedFile(const char* filename) {
 		#if defined LINUX || defined MACOSX
-			/*
-			 *	Do file mapping for reasonable systems.
-			 *	stat64(), open(), mmap()
-			 */
+
+			// Do file mapping for reasonable systems.
+			// stat64(), open(), mmap()
+
 		#ifdef MACOSX
 			if (stat(filename, &(this->st)) != 0) {
 		#else
@@ -49,12 +49,12 @@ namespace storm {
 				LOG4CPLUS_ERROR(logger, "Error in mmap(" << filename << "): " << std::strerror(errno));
 				throw exceptions::FileIoException() << "MappedFile Error in mmap(): " << std::strerror(errno);
 			}
-			this->dataend = this->data + this->st.st_size;
+			this->dataEnd = this->data + this->st.st_size;
 		#elif defined WINDOWS
-			/*
-			 *	Do file mapping for windows.
-			 *	_stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile()
-			 */
+
+			// Do file mapping for windows.
+			// _stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile()
+
 			if (_stat64(filename, &(this->st)) != 0) {
 				LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist.");
 				throw exceptions::FileIoException("MappedFile Error in stat(): Probably, this file does not exist.");
@@ -80,7 +80,7 @@ namespace storm {
 				LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ").");
 				throw exceptions::FileIoException("MappedFile Error in MapViewOfFile().");
 			}
-			this->dataend = this->data + this->st.st_size;
+			this->dataEnd = this->data + this->st.st_size;
 		#endif
 		}
 
@@ -94,10 +94,19 @@ namespace storm {
 		#endif
 		}
 
-		bool MappedFile::fileExistsAndIsReadable(const char* fileName) {
-			std::ifstream fin(fileName);
+		bool MappedFile::fileExistsAndIsReadable(const char* filename) {
+			// Test by opening an input file stream and testing the stream flags.
+			std::ifstream fin(filename);
 			return fin.good();
 		}
+
+		char* MappedFile::getData() {
+			return data;
+		}
+
+		char* MappedFile::getDataEnd() {
+			return dataEnd;
+		}
+
 	} // namespace parser
 } // namespace storm
-
diff --git a/src/parser/MappedFile.h b/src/parser/MappedFile.h
index da2df3c3d..6de9877d4 100644
--- a/src/parser/MappedFile.h
+++ b/src/parser/MappedFile.h
@@ -14,88 +14,98 @@
 
 namespace storm {
 	namespace parser {
-		/*!
-		 *	@brief Opens a file and maps it to memory providing a char*
-		 *	containing the file content.
-		 *
-		 *	This class is a very simple interface to read files efficiently.
-		 *	The given file is opened and mapped to memory using mmap().
-		 *	The public member data is a pointer to the actual file content.
-		 *	Using this method, the kernel will take care of all buffering. This is
-		 *	most probably much more efficient than doing this manually.
-		 */
 
 		#if !defined LINUX && !defined MACOSX && !defined WINDOWS
 		#error Platform not supported
 		#endif
 
+		/*!
+		 * Opens a file and maps it to memory providing a char*
+		 * containing the file content.
+		 *
+		 * This class is a very simple interface to read files efficiently.
+		 * The given file is opened and mapped to memory using mmap().
+		 * The public member data is a pointer to the actual file content.
+		 * Using this method, the kernel will take care of all buffering.
+		 * This is most probably much more efficient than doing this manually.
+		 */
 		class MappedFile {
 
 		public:
 
 			/*!
-			 * Constructor of MappedFile.
-			 * Will stat the given file, open it and map it to memory.
-			 * If anything of this fails, an appropriate exception is raised
-			 * and a log entry is written.
-			 * @param filename file to be opened
+			 * Constructs a MappedFile.
+			 * This will stat the given file, open it and map it to memory.
+			 * If anything of this fails, an appropriate exception is raised and a log entry is written.
+			 *
+			 * @param filename Path and name of the file to be opened.
 			 */
 			MappedFile(const char* filename);
 
 			/*!
-			 * Destructor of MappedFile.
-			 * Will unmap the data and close the file.
+			 * Destructs a MappedFile.
+			 * This will unmap the data and close the file.
 			 */
 			~MappedFile();
 
 			/*!
-			 *  @brief Tests whether the given file exists and is readable.
-			 *  @return True iff the file exists and is readable.
+			 * Tests whether the given file exists and is readable.
+			 *
+			 * @param filename Path and name of the file to be tested.
+			 * @return True iff the file exists and is readable.
 			 */
-			static bool fileExistsAndIsReadable(const char* fileName);
+			static bool fileExistsAndIsReadable(const char* filename);
 
 			/*!
-			 *	@brief pointer to actual file content.
+			 * Returns a pointer to the beginning of the mapped file data.
+			 *
+			 * @return A pointer to the first character of the mapped file data.
 			 */
-			char* data;
+			char* getData();
 
 			/*!
-			 *	@brief pointer to end of file content.
+			 * Returns a pointer to the end of the mapped file data.
+			 *
+			 * @return A pointer to the first position after the last character of the mapped file data.
 			 */
-			char* dataend;
+			char* getDataEnd();
 
 		private:
 
+			//! A pointer to the mapped file content.
+			char* data;
+
+			//! A pointer to end of the mapped file content.
+			char* dataEnd;
+
 		#if defined LINUX || defined MACOSX
-			/*!
-			 *	@brief file descriptor obtained by open().
-			 */
+
+			//! The file descriptor obtained by open().
 			int file;
 		#elif defined WINDOWS
+				//! The file handle obtained by opening the file.
 				HANDLE file;
+
+				//! The handle referencing the created memory mapping.
 				HANDLE mapping;
 		#endif
 
 		#if defined LINUX
-			/*!
-			 *	@brief stat information about the file.
-			 */
+
+			//! Stat information about the file.
 			struct stat64 st;
 		#elif defined MACOSX
-			/*!
-			 *	@brief stat information about the file.
-			 */
+
+			//! Stat information about the file.
 			struct stat st;
 		#elif defined WINDOWS
-			/*!
-			 *	@brief stat information about the file.
-			 */
+
+			//! Stat information about the file.
 			struct __stat64 st;
 		#endif
 		};
+
 	} // namespace parser
 } // namespace storm
 
-
-
 #endif /* STORM_PARSER_MAPPEDFILE_H_ */
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index 172d71ecd..91a01c286 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -4,38 +4,36 @@
 #include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
+	namespace parser {
 
-namespace parser {
+		storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename) {
 
-storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename) {
+			// Parse the transitions of the Markov Automaton.
+			storm::parser::MarkovAutomatonSparseTransitionParser::Result transitionResult(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(transitionsFilename));
 
-	// Parse the transitions of the Markov Automaton.
-	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType transitionResult(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(transitionsFilename));
+			// Build the actual transition matrix using the MatrixBuilder provided by the transitionResult.
+			storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0));
 
-	// Build the actual transition matrix using the MatrixBuilder provided by the transitionResult.
-	storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0));
+			// Parse the state labeling.
+			storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename));
 
-	// Parse the state labeling.
-	storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename));
+			// If given, parse the state rewards file.
+			boost::optional<std::vector<double>> stateRewards;
+			if (stateRewardFilename != "") {
+				stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(transitionMatrix.getColumnCount(), stateRewardFilename));
+			}
 
-	// If given, parse the state rewards file.
-	boost::optional<std::vector<double>> stateRewards;
-	if (stateRewardFilename != "") {
-		stateRewards.reset(storm::parser::SparseStateRewardParser::parseSparseStateReward(transitionMatrix.getColumnCount(), stateRewardFilename));
-	}
+			// Since Markov Automata do not support transition rewards no path should be given here.
+			if (transitionRewardFilename != "") {
+				LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata.");
+				throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
+			}
 
-	// Since Markov Automata do not support transition rewards no path should be given here.
-	if (transitionRewardFilename != "") {
-		LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata.");
-		throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
-	}
+			// Put the pieces together to generate the Markov Automaton.
+			storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 
-	// Put the pieces together to generate the Markov Automaton.
-	storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
-
-	return resultingAutomaton;
-}
-
-} // namespace parser
+			return resultingAutomaton;
+		}
 
+	} // namespace parser
 } // namespace storm
diff --git a/src/parser/MarkovAutomatonParser.h b/src/parser/MarkovAutomatonParser.h
index ae8005006..6f3ea5d01 100644
--- a/src/parser/MarkovAutomatonParser.h
+++ b/src/parser/MarkovAutomatonParser.h
@@ -5,28 +5,33 @@
 #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
 
 namespace storm {
-
-namespace parser {
-
-/*!
- * A class providing the functionality to parse a labeled Markov automaton.
- */
-class MarkovAutomatonParser {
-public:
-
-	/*!
-	 * Parses the given Markov automaton and returns an object representing the automaton.
-	 *
-	 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
-	 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
-	 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
-	 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton. This should be empty as transition rewards are not supported by Markov Automata.
-	 */
-	static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename);
-};
-
-} // namespace parser
-
+	namespace parser {
+
+		/*!
+		 * Loads a labeled Markov automaton from files.
+		 *
+		 * Given the file paths of the files holding the transitions, the atomic propositions and optionally the state rewards
+		 * it loads the files, parses them and returns the desired model.
+		 */
+		class MarkovAutomatonParser {
+		public:
+
+			/*!
+			 * Parses the given Markov automaton and returns an object representing the automaton.
+			 *
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The name of the file containing the transitions of the Markov automaton.
+			 * @param labelingFilename The name of the file containing the labels for the states of the Markov automaton.
+			 * @param stateRewardFilename The name of the file that contains the state reward of the Markov automaton.
+			 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton. This should be empty as transition rewards are not supported by Markov Automata.
+			 * @return The parsed MarkovAutomaton.
+			 */
+			static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename);
+		};
+
+	} // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_MARKOVAUTOMATONPARSER_H_ */
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index a899632a4..775792897 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -7,268 +7,267 @@
 
 
 namespace storm {
+	namespace parser {
 
-namespace parser {
+		using namespace storm::utility::cstring;
 
-using namespace storm::utility::cstring;
+		MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf) {
+			MarkovAutomatonSparseTransitionParser::FirstPassResult result;
 
-MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char* buf) {
-	MarkovAutomatonSparseTransitionParser::FirstPassResult result;
+			bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 
-	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
+			// Skip the format hint if it is there.
+			buf = trimWhitespaces(buf);
+			if(buf[0] < '0' || buf[0] > '9') {
+				buf = forwardToLineEnd(buf);
+				buf = trimWhitespaces(buf);
+			}
 
-	// Skip the format hint if it is there.
-	buf = trimWhitespaces(buf);
-	if(buf[0] < '0' || buf[0] > '9') {
-		buf = forwardToLineEnd(buf);
-		buf = trimWhitespaces(buf);
-	}
+			// Now read the transitions.
+			uint_fast64_t source, target = 0;
+			uint_fast64_t lastsource = 0;
+			bool encounteredEOF = false;
+			bool stateHasMarkovianChoice = false;
+			bool stateHasProbabilisticChoice = false;
+			while (buf[0] != '\0' && !encounteredEOF) {
+				// At the current point, the next thing to read is the source state of the next choice to come.
+				source = checked_strtol(buf, &buf);
+
+				// Check if we encountered a state index that is bigger than all previously seen ones and record it if necessary.
+				if (source > result.highestStateIndex) {
+					result.highestStateIndex = source;
+				}
 
-	// Now read the transitions.
-	uint_fast64_t source, target = 0;
-	uint_fast64_t lastsource = 0;
-	bool encounteredEOF = false;
-	bool stateHasMarkovianChoice = false;
-	bool stateHasProbabilisticChoice = false;
-	while (buf[0] != '\0' && !encounteredEOF) {
-		// At the current point, the next thing to read is the source state of the next choice to come.
-		source = checked_strtol(buf, &buf);
+				// If we have skipped some states, we need to reserve the space for the self-loop insertion in the second pass.
+				if (source > lastsource + 1) {
+					if (fixDeadlocks) {
+						result.numberOfNonzeroEntries += source - lastsource - 1;
+						result.numberOfChoices += source - lastsource - 1;
+					} else {
+						LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
+						throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
+					}
+				} else if (source < lastsource) {
+					LOG4CPLUS_ERROR(logger, "Illegal state choice order. A choice of state " << source << " appears at an illegal position.");
+					throw storm::exceptions::WrongFormatException() << "Illegal state choice order. A choice of state " << source << " appears at an illegal position.";
+				}
 
-		// Check if we encountered a state index that is bigger than all previously seen ones and record it if necessary.
-		if (source > result.highestStateIndex) {
-			result.highestStateIndex = source;
-		}
+				++result.numberOfChoices;
 
-		// If we have skipped some states, we need to reserve the space for the self-loop insertion in the second pass.
-		if (source > lastsource + 1) {
-			if (fixDeadlocks) {
-				result.numberOfNonzeroEntries += source - lastsource - 1;
-				result.numberOfChoices += source - lastsource - 1;
-			} else {
-				LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
-				throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
-			}
-		} else if (source < lastsource) {
-			LOG4CPLUS_ERROR(logger, "Illegal state choice order. A choice of state " << source << " appears at an illegal position.");
-			throw storm::exceptions::WrongFormatException() << "Illegal state choice order. A choice of state " << source << " appears at an illegal position.";
-		}
+				// If we have moved to the next state, we need to clear the flag that stores whether or not the source has a Markovian or probabilistic choice.
+				if (source != lastsource) {
+					stateHasMarkovianChoice = false;
+					stateHasProbabilisticChoice = false;
+				}
 
-		++result.numberOfChoices;
+				// Record that the current source was the last source.
+				lastsource = source;
 
-		// If we have moved to the next state, we need to clear the flag that stores whether or not the source has a Markovian or probabilistic choice.
-		if (source != lastsource) {
-			stateHasMarkovianChoice = false;
-			stateHasProbabilisticChoice = false;
-		}
+				buf = trimWhitespaces(buf);
 
-		// Record that the current source was the last source.
-		lastsource = source;
+				// Depending on the action name, the choice is either a probabilitic one or a markovian one.
+				bool isMarkovianChoice = false;
+				if (buf[0] == '!' &&  skipWord(buf) - buf == 1) {
+					isMarkovianChoice = true;
+				}else {
+					isMarkovianChoice = false;
+				}
+				buf = skipWord(buf);
 
-		buf = trimWhitespaces(buf);
+				if (isMarkovianChoice) {
+					if (stateHasMarkovianChoice) {
+						LOG4CPLUS_ERROR(logger, "The state " << source << " has multiple Markovian choices.");
+						throw storm::exceptions::WrongFormatException() << "The state " << source << " has multiple Markovian choices.";
+					}
+					if (stateHasProbabilisticChoice) {
+						LOG4CPLUS_ERROR(logger, "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.");
+						throw storm::exceptions::WrongFormatException() << "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.";
+					}
+					stateHasMarkovianChoice = true;
+				} else {
+					stateHasProbabilisticChoice = true;
+				}
 
-		// Depending on the action name, the choice is either a probabilitic one or a markovian one.
-		bool isMarkovianChoice = false;
-		if (buf[0] == '!' &&  skipWord(buf) - buf == 1) {
-			isMarkovianChoice = true;
-		}else {
-			isMarkovianChoice = false;
-		}
-		buf = skipWord(buf);
+				// Go to the next line where the transitions start.
+				buf = forwardToNextLine(buf);
 
-		if (isMarkovianChoice) {
-			if (stateHasMarkovianChoice) {
-				LOG4CPLUS_ERROR(logger, "The state " << source << " has multiple Markovian choices.");
-				throw storm::exceptions::WrongFormatException() << "The state " << source << " has multiple Markovian choices.";
-			}
-			if (stateHasProbabilisticChoice) {
-				LOG4CPLUS_ERROR(logger, "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.");
-				throw storm::exceptions::WrongFormatException() << "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.";
+				// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
+				bool hasSuccessorState = false;
+				bool encounteredNewDistribution = false;
+				uint_fast64_t lastSuccessorState = 0;
+
+				// At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
+				do {
+					buf = trimWhitespaces(buf);
+					// If the end of the file was reached, we need to abort and check whether we are in a legal state.
+					if (buf[0] == '\0') {
+						if (!hasSuccessorState) {
+							LOG4CPLUS_ERROR(logger, "Premature end-of-file. Expected at least one successor state for state " << source << ".");
+							throw storm::exceptions::WrongFormatException() << "Premature end-of-file. Expected at least one successor state for state " << source << ".";
+						} else {
+							// If there was at least one successor for the current choice, this is legal and we need to move on.
+							encounteredEOF = true;
+						}
+					} else if (buf[0] == '*') {
+						// As we have encountered a "*", we know that there is an additional successor state for the current choice.
+						buf= skipWord(buf);
+
+						// Now we need to read the successor state and check if we already saw a higher state index.
+						target = checked_strtol(buf, &buf);
+						if (target > result.highestStateIndex) {
+							result.highestStateIndex = target;
+						}
+						if (hasSuccessorState && target <= lastSuccessorState) {
+							LOG4CPLUS_ERROR(logger, "Illegal transition order for source state " << source << ".");
+							throw storm::exceptions::WrongFormatException() << "Illegal transition order for source state " << source << ".";
+						}
+
+						// And the corresponding probability/rate.
+						double val = checked_strtod(buf, &buf);
+						if (val <= 0.0) {
+							LOG4CPLUS_ERROR(logger, "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
+							throw storm::exceptions::WrongFormatException() << "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
+						}
+
+						// We need to record that we found at least one successor state for the current choice.
+						hasSuccessorState = true;
+						lastSuccessorState = target;
+
+						// As we found a new successor, we need to increase the number of nonzero entries.
+						++result.numberOfNonzeroEntries;
+
+						buf = forwardToNextLine(buf);
+					} else {
+						// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
+						// to the buffer, because we still need to read the new source state.
+						encounteredNewDistribution = true;
+					}
+				} while (!encounteredEOF && !encounteredNewDistribution);
 			}
-			stateHasMarkovianChoice = true;
-		} else {
-			stateHasProbabilisticChoice = true;
+
+			return result;
 		}
 
-		// Go to the next line where the transitions start.
-		buf = forwardToNextLine(buf);
+		MarkovAutomatonSparseTransitionParser::Result MarkovAutomatonSparseTransitionParser::secondPass(char* buf, FirstPassResult const& firstPassResult) {
+			Result result(firstPassResult);
 
-		// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
-		bool hasSuccessorState = false;
-		bool encounteredNewDistribution = false;
-		uint_fast64_t lastSuccessorState = 0;
+			bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 
-		// At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
-		do {
+			// Skip the format hint if it is there.
 			buf = trimWhitespaces(buf);
-			// If the end of the file was reached, we need to abort and check whether we are in a legal state.
-			if (buf[0] == '\0') {
-				if (!hasSuccessorState) {
-					LOG4CPLUS_ERROR(logger, "Premature end-of-file. Expected at least one successor state for state " << source << ".");
-					throw storm::exceptions::WrongFormatException() << "Premature end-of-file. Expected at least one successor state for state " << source << ".";
-				} else {
-					// If there was at least one successor for the current choice, this is legal and we need to move on.
-					encounteredEOF = true;
-				}
-			} else if (buf[0] == '*') {
-				// As we have encountered a "*", we know that there is an additional successor state for the current choice.
-				buf= skipWord(buf);
-
-				// Now we need to read the successor state and check if we already saw a higher state index.
-				target = checked_strtol(buf, &buf);
-				if (target > result.highestStateIndex) {
-					result.highestStateIndex = target;
-				}
-				if (hasSuccessorState && target <= lastSuccessorState) {
-					LOG4CPLUS_ERROR(logger, "Illegal transition order for source state " << source << ".");
-					throw storm::exceptions::WrongFormatException() << "Illegal transition order for source state " << source << ".";
-				}
+			if(buf[0] < '0' || buf[0] > '9') {
+				buf = forwardToLineEnd(buf);
+				buf = trimWhitespaces(buf);
+			}
 
-				// And the corresponding probability/rate.
-				double val = checked_strtod(buf, &buf);
-				if (val <= 0.0) {
-					LOG4CPLUS_ERROR(logger, "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
-					throw storm::exceptions::WrongFormatException() << "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
+			// Now read the transitions.
+			uint_fast64_t source, target = 0;
+			uint_fast64_t lastsource = 0;
+			bool encounteredEOF = false;
+			uint_fast64_t currentChoice = 0;
+			while (buf[0] != '\0' && !encounteredEOF) {
+				// At the current point, the next thing to read is the source state of the next choice to come.
+				source = checked_strtol(buf, &buf);
+
+				// If we have skipped some states, we need to insert self-loops if requested.
+				if (source > lastsource + 1) {
+					if (fixDeadlocks) {
+						for (uint_fast64_t index = lastsource + 1; index < source; ++index) {
+							result.nondeterministicChoiceIndices[index] = currentChoice;
+							result.transitionMatrixBuilder.addNextValue(currentChoice, index, 1);
+							++currentChoice;
+						}
+					} else {
+						LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
+						throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
+					}
 				}
 
-				// We need to record that we found at least one successor state for the current choice.
-				hasSuccessorState = true;
-				lastSuccessorState = target;
-
-				// As we found a new successor, we need to increase the number of nonzero entries.
-				++result.numberOfNonzeroEntries;
-
-				buf = forwardToNextLine(buf);
-			} else {
-				// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
-				// to the buffer, because we still need to read the new source state.
-				encounteredNewDistribution = true;
-			}
-		} while (!encounteredEOF && !encounteredNewDistribution);
-	}
-
-	return result;
-}
-
-MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::secondPass(char* buf, FirstPassResult const& firstPassResult) {
-	ResultType result(firstPassResult);
-
-	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-
-	// Skip the format hint if it is there.
-	buf = trimWhitespaces(buf);
-	if(buf[0] < '0' || buf[0] > '9') {
-		buf = forwardToLineEnd(buf);
-		buf = trimWhitespaces(buf);
-	}
-
-	// Now read the transitions.
-	uint_fast64_t source, target = 0;
-	uint_fast64_t lastsource = 0;
-	bool encounteredEOF = false;
-	uint_fast64_t currentChoice = 0;
-	while (buf[0] != '\0' && !encounteredEOF) {
-		// At the current point, the next thing to read is the source state of the next choice to come.
-		source = checked_strtol(buf, &buf);
-
-		// If we have skipped some states, we need to insert self-loops if requested.
-		if (source > lastsource + 1) {
-			if (fixDeadlocks) {
-				for (uint_fast64_t index = lastsource + 1; index < source; ++index) {
-					result.nondeterministicChoiceIndices[index] = currentChoice;
-					result.transitionMatrixBuilder.addNextValue(currentChoice, index, 1);
-					++currentChoice;
+				if (source != lastsource) {
+					// If we skipped to a new state we need to record the beginning of the choices in the nondeterministic choice indices.
+					result.nondeterministicChoiceIndices[source] = currentChoice;
 				}
-			} else {
-				LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
-				throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
-			}
-		}
 
-		if (source != lastsource) {
-			// If we skipped to a new state we need to record the beginning of the choices in the nondeterministic choice indices.
-			result.nondeterministicChoiceIndices[source] = currentChoice;
-		}
+				// Record that the current source was the last source.
+				lastsource = source;
 
-		// Record that the current source was the last source.
-		lastsource = source;
+				buf = trimWhitespaces(buf);
 
-		buf = trimWhitespaces(buf);
+				// Depending on the action name, the choice is either a probabilitic one or a markovian one.
+				bool isMarkovianChoice = false;
+				if (buf[0] == '!' && skipWord(buf) - buf == 1) {
+					isMarkovianChoice = true;
 
-		// Depending on the action name, the choice is either a probabilitic one or a markovian one.
-		bool isMarkovianChoice = false;
-		if (buf[0] == '!' && skipWord(buf) - buf == 1) {
-			isMarkovianChoice = true;
+					// Mark the current state as a Markovian one.
+					result.markovianStates.set(source, true);
+				} else {
+					isMarkovianChoice = false;
+				}
 
-			// Mark the current state as a Markovian one.
-			result.markovianStates.set(source, true);
-		} else {
-			isMarkovianChoice = false;
-		}
+				// Go to the next line where the transitions start.
+				buf = forwardToNextLine(buf);
 
-		// Go to the next line where the transitions start.
-		buf = forwardToNextLine(buf);
+				// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
+				bool encounteredNewDistribution = false;
 
-		// Now that we have the source state and the information whether or not the current choice is probabilistic or Markovian, we need to read the list of successors and the probabilities/rates.
-		bool encounteredNewDistribution = false;
+				// At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
+				do {
+					buf = trimWhitespaces(buf);
 
-		// At this point, we need to check whether there is an additional successor or we have reached the next choice for the same or a different state.
-		do {
-			buf = trimWhitespaces(buf);
+					// If the end of the file was reached, we need to abort and check whether we are in a legal state.
+					if (buf[0] == '\0') {
+						// Under the assumption that the currently open choice has at least one successor (which is given after the first run)
+						// we may legally stop reading here.
+						encounteredEOF = true;
+					} else if (buf[0] == '*') {
 
-			// If the end of the file was reached, we need to abort and check whether we are in a legal state.
-			if (buf[0] == '\0') {
-				// Under the assumption that the currently open choice has at least one successor (which is given after the first run)
-				// we may legally stop reading here.
-				encounteredEOF = true;
-			} else if (buf[0] == '*') {
+						// As we have encountered a "*", we know that there is an additional successor state for the current choice.
+						buf = skipWord(buf);
 
-				// As we have encountered a "*", we know that there is an additional successor state for the current choice.
-				buf = skipWord(buf);
+						// Now we need to read the successor state and check if we already saw a higher state index.
+						target = checked_strtol(buf, &buf);
 
-				// Now we need to read the successor state and check if we already saw a higher state index.
-				target = checked_strtol(buf, &buf);
+						// And the corresponding probability/rate.
+						double val = checked_strtod(buf, &buf);
 
-				// And the corresponding probability/rate.
-				double val = checked_strtod(buf, &buf);
+						// Record the value as well as the exit rate in case of a Markovian choice.
+						result.transitionMatrixBuilder.addNextValue(currentChoice, target, val);
+						if (isMarkovianChoice) {
+							result.exitRates[source] += val;
+						}
 
-				// Record the value as well as the exit rate in case of a Markovian choice.
-				result.transitionMatrixBuilder.addNextValue(currentChoice, target, val);
-				if (isMarkovianChoice) {
-					result.exitRates[source] += val;
-				}
+						buf = forwardToNextLine(buf);
+					} else {
+						// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
+						// to the buffer, because we still need to read the new source state.
+						encounteredNewDistribution = true;
+					}
+				} while (!encounteredEOF && !encounteredNewDistribution);
 
-				buf = forwardToNextLine(buf);
-			} else {
-				// If it was not a "*", we have to assume that we encountered the beginning of a new choice definition. In this case, we don't move the pointer
-				// to the buffer, because we still need to read the new source state.
-				encounteredNewDistribution = true;
+				++currentChoice;
 			}
-		} while (!encounteredEOF && !encounteredNewDistribution);
-
-		++currentChoice;
-	}
 
-	// Put a sentinel element at the end.
-	result.nondeterministicChoiceIndices[firstPassResult.highestStateIndex + 1] = currentChoice;
+			// Put a sentinel element at the end.
+			result.nondeterministicChoiceIndices[firstPassResult.highestStateIndex + 1] = currentChoice;
 
-	return result;
-}
+			return result;
+		}
 
-MarkovAutomatonSparseTransitionParser::ResultType MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(std::string const& filename) {
-	// Set the locale to correctly recognize floating point numbers.
-	setlocale(LC_NUMERIC, "C");
+		MarkovAutomatonSparseTransitionParser::Result MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(std::string const& filename) {
+			// Set the locale to correctly recognize floating point numbers.
+			setlocale(LC_NUMERIC, "C");
 
-	if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-		throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
-	}
+			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
+				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+				throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
+			}
 
-	// Open file and prepare pointer to buffer.
-	MappedFile file(filename.c_str());
-	char* buf = file.data;
+			// Open file and prepare pointer to buffer.
+			MappedFile file(filename.c_str());
+			char* buf = file.getData();
 
-	return secondPass(buf, firstPass(buf));
-}
+			return secondPass(buf, firstPass(buf));
+		}
 
-} // namespace parser
+	} // namespace parser
 } // namespace storm
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index 954f21a63..c6019d934 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -5,93 +5,102 @@
 #include "src/storage/BitVector.h"
 
 namespace storm {
-
-namespace parser {
-
-/*
- * A class providing the functionality to parse the transitions of a Markov automaton.
- */
-class MarkovAutomatonSparseTransitionParser {
-public:
-	/*
-	 * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model, the highest state index
-	 * and the total number of choices.
-	 */
-	struct FirstPassResult {
-
-		FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0), numberOfChoices(0) {
-			// Intentionally left empty.
-		}
-
-		// The total number of non-zero entries of the model.
-		uint_fast64_t numberOfNonzeroEntries;
-
-		// The highest state index that appears in the model.
-		uint_fast64_t highestStateIndex;
-
-		// The total number of nondeterministic choices in the model.
-		uint_fast64_t numberOfChoices;
-	};
-
-	/*
-	 * A structure representing the result of the parser. It contains the sparse matrix that represents the transitions (along with a vector indicating
-	 * at which index the choices of a given state begin) as well as the exit rates for all Markovian choices.
-	 */
-	struct ResultType {
-
-		/*
-		 * Creates a new instance of the struct using the result of the first pass to correctly initialize the container.
-		 * @param firstPassResult A reference to the result of the first pass.
+	namespace parser {
+
+		/*!
+		 * A class providing the functionality to parse the transitions of a Markov automaton.
+		 *
+		 * The file is parsed in two passes.
+		 * The first pass tests the file format and collects statistical data needed for the second pass.
+		 * The second pass then collects the actual file data and compiles it into a ResultType.
 		 */
-		ResultType(FirstPassResult const& firstPassResult) : transitionMatrixBuilder(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1, firstPassResult.numberOfNonzeroEntries), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
-			// Intentionally left empty.
-		}
-
-		// A matrix representing the transitions of the model.
-		storm::storage::SparseMatrixBuilder<double> transitionMatrixBuilder;
-
-		// A vector indicating which rows of the matrix represent the choices of a given state.
-		std::vector<uint_fast64_t> nondeterministicChoiceIndices;
-
-		// A bit vector indicating which choices are Markovian. By duality, all other choices are probabilitic.
-		storm::storage::BitVector markovianChoices;
-
-		// A bit vector indicating which states possess a Markovian choice.
-		storm::storage::BitVector markovianStates;
-
-		// A vector that stores the exit rates for each state. For all states that do not possess Markovian choices this is equal to 0.
-		std::vector<double> exitRates;
-	};
-
-	/*!
-	 * Parses the given file under the assumption that it contains a Markov automaton specified in the appropriate format.
-	 *
-	 * @param filename The name of the file to parse.
-	 * @return A structure representing the result of the parser.
-	 */
-	static ResultType parseMarkovAutomatonTransitions(std::string const& filename);
-
-private:
-	/*
-	 * Performs the first pass on the input pointed to by the given buffer.
-	 *
-	 * @param buffer The buffer that cointains the input.
-	 * @return A structure representing the result of the first pass.
-	 */
-	static FirstPassResult firstPass(char* buffer);
-
-	/*
-	 * Performs the second pass on the input pointed to by the given buffer with the information of the first pass.
-	 *
-	 * @param buffer The buffer that cointains the input.
-	 * @param firstPassResult The result of the first pass performed on the same input.
-	 * @return A structure representing the result of the second pass.
-	 */
-	static ResultType secondPass(char* buffer, FirstPassResult const& firstPassResult);
-};
-
-} // namespace parser
-
+		class MarkovAutomatonSparseTransitionParser {
+		public:
+
+			/*!
+			 * A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model, the highest state index
+			 * and the total number of choices.
+			 */
+			struct FirstPassResult {
+
+				/*!
+				 * The default constructor.
+				 * Constructs an empty FirstPassResult.
+				 */
+				FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0), numberOfChoices(0) {
+					// Intentionally left empty.
+				}
+
+				//! The total number of non-zero entries of the model.
+				uint_fast64_t numberOfNonzeroEntries;
+
+				//! The highest state index that appears in the model.
+				uint_fast64_t highestStateIndex;
+
+				//! The total number of nondeterministic choices in the model.
+				uint_fast64_t numberOfChoices;
+			};
+
+			/*!
+			 * A structure representing the result of the parser. It contains the sparse matrix that represents the transitions (along with a vector indicating
+			 * at which index the choices of a given state begin) as well as the exit rates for all Markovian choices.
+			 */
+			struct Result {
+
+				/*!
+				 * Creates a new instance of the struct using the result of the first pass to correctly initialize the container.
+				 *
+				 * @param firstPassResult A reference to the result of the first pass.
+				 */
+				Result(FirstPassResult const& firstPassResult) : transitionMatrixBuilder(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1, firstPassResult.numberOfNonzeroEntries), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
+					// Intentionally left empty.
+				}
+
+				//! A matrix representing the transitions of the model.
+				storm::storage::SparseMatrixBuilder<double> transitionMatrixBuilder;
+
+				//! A vector indicating which rows of the matrix represent the choices of a given state.
+				std::vector<uint_fast64_t> nondeterministicChoiceIndices;
+
+				//! A bit vector indicating which choices are Markovian. By duality, all other choices are probabilitic.
+				storm::storage::BitVector markovianChoices;
+
+				//! A bit vector indicating which states possess a Markovian choice.
+				storm::storage::BitVector markovianStates;
+
+				//! A vector that stores the exit rates for each state. For all states that do not possess Markovian choices this is equal to 0.
+				std::vector<double> exitRates;
+			};
+
+			/*!
+			 * Parses the given file under the assumption that it contains a Markov automaton specified in the appropriate format.
+			 *
+			 * @param filename The name of the file to parse.
+			 * @return A structure representing the result of the parser.
+			 */
+			static Result parseMarkovAutomatonTransitions(std::string const& filename);
+
+		private:
+
+			/*!
+			 * Performs the first pass on the input pointed to by the given buffer.
+			 *
+			 * @param buffer The buffer that cointains the input.
+			 * @return A structure representing the result of the first pass.
+			 */
+			static FirstPassResult firstPass(char* buffer);
+
+			/*!
+			 * Performs the second pass on the input pointed to by the given buffer with the information of the first pass.
+			 *
+			 * @param buffer The buffer that cointains the input.
+			 * @param firstPassResult The result of the first pass performed on the same input.
+			 * @return A structure representing the result of the second pass.
+			 */
+			static Result secondPass(char* buffer, FirstPassResult const& firstPassResult);
+		};
+
+	} // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_MARKOVAUTOMATONSPARSETRANSITIONPARSER_H_ */
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index 82a7f3085..d150b8c84 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -17,36 +17,26 @@
 namespace storm {
 	namespace parser {
 
-		/*!
-		 * Parses a transition file and a labeling file and produces an intermediate Result Container
-		 * Note that the labeling file may have at most as many nodes as the transition file!
-		 *
-		 * @param transitionSystemFile String containing the location of the transition file (....tra)
-		 * @param labelingFile String containing the location of the labeling file (....lab)
-		 * @param stateRewardFile String containing the location of the state reward file (...srew)
-		 * @param transitionRewardFile String containing the location of the transition reward file (...trew)
-		 */
-		NondeterministicModelParser::Result NondeterministicModelParser::parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
-				std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+		NondeterministicModelParser::Result NondeterministicModelParser::parseNondeterministicModel(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
 			// Parse the transitions.
-			NondeterministicSparseTransitionParser::Result transitions(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionSystemFile)));
+			NondeterministicSparseTransitionParser::Result transitions(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionsFilename)));
 
 			uint_fast64_t stateCount = transitions.transitionMatrix.getColumnCount();
 
 			// Parse the state labeling.
-			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
+			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFilename)));
 
 			// Only parse state rewards if a file is given.
 			boost::optional<std::vector<double>> stateRewards;
-			if (stateRewardFile != "") {
-				stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFile);
+			if (stateRewardFilename != "") {
+				stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFilename);
 			}
 
 			// Only parse transition rewards if a file is given.
 			boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
-			if (transitionRewardFile != "") {
-				transitionRewards = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFile, transitions).transitionMatrix;
+			if (transitionRewardFilename != "") {
+				transitionRewards = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFilename, transitions).transitionMatrix;
 			}
 
 			// Construct the result.
@@ -57,25 +47,15 @@ namespace storm {
 			return result;
 		}
 
-		/*!
-		 * Uses the Function parseNondeterministicModel internally to parse the given input files.
-		 * @note This is a Short-Hand for Constructing a Mdp directly from the data returned by @parseNondeterministicModel
-		 * @return A Mdp Model
-		 */
-		storm::models::Mdp<double> NondeterministicModelParser::parseMdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+		storm::models::Mdp<double> NondeterministicModelParser::parseMdp(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
-			Result parserResult = parseNondeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile);
+			Result parserResult = parseNondeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename);
 			return storm::models::Mdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 		}
 
-		/*!
-		 * Uses the Function parseNondeterministicModel internally to parse the given input files.
-		 * @note This is a Short-Hand for Constructing a Ctmdp directly from the data returned by @parseNondeterministicModel
-		 * @return A Ctmdp Model
-		 */
-		storm::models::Ctmdp<double> NondeterministicModelParser::parseCtmdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile, std::string const & transitionRewardFile) {
+		storm::models::Ctmdp<double> NondeterministicModelParser::parseCtmdp(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
-			Result parserResult = parseNondeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile);
+			Result parserResult = parseNondeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename);
 			return storm::models::Ctmdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 		}
 
diff --git a/src/parser/NondeterministicModelParser.h b/src/parser/NondeterministicModelParser.h
index 50a0525fb..376c3e8c6 100644
--- a/src/parser/NondeterministicModelParser.h
+++ b/src/parser/NondeterministicModelParser.h
@@ -14,62 +14,121 @@
 namespace storm {
 	namespace parser {
 
+		/*!
+		 * Loads a nondeterministic model (Mdp or Ctmdp) from files.
+		 *
+		 * Given the file paths of the files holding the transitions, the atomic propositions and optionally the state- and transition rewards
+		 * it loads the files, parses them and returns the desired model.
+		 */
 		class NondeterministicModelParser {
 
 		public:
 
 			/*!
-			 * @brief This Class acts as a container much like std::pair for the five return values of the NondeterministicModelParser
+			 * A structure containing the parsed components of a nondeterministic model.
 			 */
 			struct Result {
 
+				/*!
+				 * The copy constructor.
+				 *
+				 * @param transitionSystem The transition system to be contained in the Result.
+				 * @param rowMapping The mapping between matrix rows and model states to be contained in the Result.
+				 * @param labeling The the labeling of the transition system to be contained in the Result.
+				 */
 				Result(storm::storage::SparseMatrix<double>& transitionSystem, std::vector<uint_fast64_t>& rowMapping, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling), rowMapping(rowMapping) {
 					// Intentionally left empty.
 				}
 
+				/*!
+				 * The move constructor.
+				 *
+				 * @param transitionSystem The transition system to be contained in the Result.
+				 * @param rowMapping The mapping between matrix rows and model states to be contained in the Result.
+				 * @param labeling The the labeling of the transition system to be contained in the Result.
+				 */
 				Result(storm::storage::SparseMatrix<double>&& transitionSystem, std::vector<uint_fast64_t>&& rowMapping, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)), rowMapping(std::move(rowMapping)) {
 					// Intentionally left empty.
 				}
 
-				// A matrix representing the transitions of the model
+				/*!
+				 * A matrix representing the transitions of the model
+				 */
 				storm::storage::SparseMatrix<double> transitionSystem;
 
-				// The labels of each state.
+				/*!
+				 * The labels of each state.
+				 */
 				storm::models::AtomicPropositionsLabeling labeling;
 
-				// A mapping from rows of the matrix to states of the model.
-				// This resolves the nondeterministic choices inside the transition system.
+				/*!
+				 * A mapping from rows of the matrix to states of the model.
+                 * This resolves the nondeterministic choices inside the transition system.
+				 */
 				std::vector<uint_fast64_t> rowMapping;
 
-				// Optional rewards for each state.
+				/*!
+				 * Optional rewards for each state.
+				 */
 				boost::optional<std::vector<double>> stateRewards;
 
-				// Optional rewards for each transition.
+				/*!
+				 * Optional rewards for each transition.
+				 */
 				boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
 			};
 
 			/*!
-			 *	@brief Load label and transition file and return initialized Mdp object
+			 * Parse a Mdp.
 			 *
-			 *	@note This class creates a new Mdp object that can
-			 *	be accessed via getMdp(). However, it will not delete this object!
+			 * This method is an adapter to the actual parsing function.
+			 * I.e. it uses @parseNondeterministicModel internally to parse the given input files, takes its result and compiles it into a Dtmc.
 			 *
-			 *	@note The labeling representation in the file may use at most as much nodes as are specified in the mdp.
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
+			 * @return The parsed Mdp.
 			 */
-			static storm::models::Mdp<double> parseMdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+			static storm::models::Mdp<double> parseMdp(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename = "", std::string const & transitionRewardFilename = "");
 
 
 			/*!
+			 * Parse a Ctmdp.
+			 *
+			 * This method is an adapter to the actual parsing function.
+			 * I.e. it uses @parseNondeterministicModel internally to parse the given input files, takes its result and compiles it into a Dtmc.
 			 *
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
+			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
+			 * @return The parsed Ctmdp.
 			 */
-			static storm::models::Ctmdp<double> parseCtmdp(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+			static storm::models::Ctmdp<double> parseCtmdp(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename = "", std::string const & transitionRewardFilename = "");
 
 		private:
 
 			/*!
+			 * Parses a nondeterministic model from the given files.
+			 * Calls sub-parsers on the given files and fills the container with the results.
+			 *
+			 * @note The number of states of the model is determined by the transitions file.
+			 *       The labeling file may therefore not contain labels of states that are not contained in the transitions file.
 			 *
+			 * @param transitionsFilename The path and name of the file containing the transitions of the model.
+			 * @param labelingFilename The path and name of the file containing the labels for the states of the model.
+			 * @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
+			 * @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
+			 * @return The parsed model encapsulated in a Result structure.
 			 */
-			static Result parseNondeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile, std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
+			static Result parseNondeterministicModel(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename = "", std::string const & transitionRewardFilename = "");
 
 		};
 
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 6e7c72246..6dc1ffbc2 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -49,10 +49,10 @@ namespace storm {
 
 			// Open file.
 			MappedFile file(filename.c_str());
-			char* buf = file.data;
+			char* buf = file.getData();
 
 			// Perform first pass, i.e. obtain number of columns, rows and non-zero elements.
-			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.data, isRewardFile, modelInformation);
+			NondeterministicSparseTransitionParser::FirstPassResult firstPass = NondeterministicSparseTransitionParser::firstPass(file.getData(), isRewardFile, modelInformation);
 
 			// If first pass returned zero, the file format was wrong.
 			if (firstPass.numberOfNonzeroEntries == 0) {
diff --git a/src/parser/NondeterministicSparseTransitionParser.h b/src/parser/NondeterministicSparseTransitionParser.h
index d754a39c3..aea0f8fcc 100644
--- a/src/parser/NondeterministicSparseTransitionParser.h
+++ b/src/parser/NondeterministicSparseTransitionParser.h
@@ -8,27 +8,38 @@
 namespace storm {
 	namespace parser {
 
+		/*!
+		 * A class providing the functionality to parse the transitions of a nondeterministic model.
+		 *
+		 * The file is parsed in two passes.
+		 * The first pass tests the file format and collects statistical data needed for the second pass.
+		 * The second pass then collects the actual file data and compiles it into a Result.
+		 */
 		class NondeterministicSparseTransitionParser {
 
 		public:
 
-			/*
+			/*!
 			 * A structure representing the result of the first pass of this parser.
 			 * It contains the number of non-zero entries in the model, the highest state index and the total number if nondeterministic choices.
 			 */
 			struct FirstPassResult {
 
+				/*!
+				 * The default constructor.
+				 * Constructs an empty FirstPassResult.
+				 */
 				FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0), choices(0) {
 					// Intentionally left empty.
 				}
 
-				// The total number of non-zero entries of the model.
+				//! The total number of non-zero entries of the model.
 				uint_fast64_t numberOfNonzeroEntries;
 
-				// The highest state index that appears in the model.
+				//! The highest state index that appears in the model.
 				uint_fast64_t highestStateIndex;
 
-				// The total number of nondeterministic choices within the transition system.
+				//! The total number of nondeterministic choices within the transition system.
 				uint_fast64_t choices;
 			};
 
@@ -38,37 +49,47 @@ namespace storm {
 			 */
 			struct Result {
 
-				// Constructs an empty Result.
+				/*!
+				 *  The default constructor.
+				 *  Constructs an empty Result.
+				 */
 				Result() : transitionMatrix(), rowMapping() {
 					// Intentionally left empty.
 				}
 
-				// Constructs a Result, initializing its members with the given values.
+				/*!
+				 * Constructs a Result, initializing its members with the given values.
+				 *
+				 * @param transitionMatrix The matrix containing the parsed transition system.
+				 * @param rowMapping A mapping from rows of the matrix to states of the model.
+				 */
 				Result(storm::storage::SparseMatrix<double> transitionMatrix, std::vector<uint_fast64_t> rowMapping) : transitionMatrix(transitionMatrix), rowMapping(rowMapping) {
 					// Intentionally left empty.
 				}
 
-				// The matrix containing the parsed transition system.
+				/*!
+				 * The matrix containing the parsed transition system.
+				 */
 				storm::storage::SparseMatrix<double> transitionMatrix;
 
-				// A mapping from rows of the matrix to states of the model.
-				// This resolves the nondeterministic choices inside the transition system.
+				/*!
+				 * A mapping from rows of the matrix to states of the model.
+				 * This resolves the nondeterministic choices inside the transition system.
+				 */
 				std::vector<uint_fast64_t> rowMapping;
 			};
 
 			/*!
-			 * @brief Load a nondeterministic transition system from file and create a
-			 *        sparse adjacency matrix whose entries represent the weights of the edges
+			 * Load a nondeterministic transition system from file and create a sparse adjacency matrix whose entries represent the weights of the edges
 			 *
-			 * @param filename The path of file to be parsed.
+			 * @param filename The path and name of file to be parsed.
 			 */
 			static Result parseNondeterministicTransitions(std::string const & filename);
 
 			/*!
-			 *	@brief	Load a nondeterministic transition system from file and create a
-			 *	sparse adjacency matrix whose entries represent the weights of the edges
+			 * Load a nondeterministic transition system from file and create a sparse adjacency matrix whose entries represent the weights of the edges
 			 *
-			 * @param filename The path of file to be parsed.
+			 * @param filename The path and name of file to be parsed.
 			 * @param modelInformation The information about the transition structure of nondeterministic model in which the transition rewards shall be used.
 			 * @return A struct containing the parsed file contents, i.e. the transition reward matrix and the mapping between its rows and the states of the model.
 			 */
@@ -95,7 +116,7 @@ namespace storm {
 			 * The main parsing routine.
 			 * Opens the given file, calls the first pass and performs the second pass, parsing the content of the file into a SparseMatrix.
 			 *
-			 * @param filename The path of file to be parsed.
+			 * @param filename The path and name of file to be parsed.
 			 * @param rewardFile A flag set iff the file to be parsed contains transition rewards.
 			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 			 * @param modelInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index c79e6f691..ad4d815de 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -7,10 +7,7 @@
 
 #include "src/parser/SparseStateRewardParser.h"
 
-#include <iostream>
-
 #include "src/exceptions/WrongFormatException.h"
-#include "src/exceptions/FileIoException.h"
 #include "src/utility/cstring.h"
 #include "src/parser/MappedFile.h"
 #include "log4cplus/logger.h"
@@ -18,52 +15,43 @@
 extern log4cplus::Logger logger;
 
 namespace storm {
-
-namespace parser {
-
-using namespace storm::utility::cstring;
-
-/*!
- *	Reads a state reward file and puts the result in a state reward vector.
- *
- *	@param stateCount The number of states.
- *	@param filename The filename of the state reward file.
- *	@return The created state reward vector.
- */
-std::vector<double> SparseStateRewardParser::parseSparseStateReward(uint_fast64_t stateCount, std::string const & filename) {
-	// Open file.
-	if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-		throw storm::exceptions::WrongFormatException();
-	}
-
-	MappedFile file(filename.c_str());
-	char* buf = file.data;
-
-	// Create state reward vector with given state count.
-	std::vector<double> stateRewards(stateCount);
-
-	// Now parse state reward assignments.
-	uint_fast64_t state;
-	double reward;
-
-	// Iterate over states.
-	while (buf[0] != '\0') {
-		// Parse state number and reward value.
-		state = checked_strtol(buf, &buf);
-		reward = checked_strtod(buf, &buf);
-		if (reward < 0.0) {
-			LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\".");
-			throw storm::exceptions::WrongFormatException() << "State reward file specifies illegal reward value.";
+	namespace parser {
+
+		using namespace storm::utility::cstring;
+
+		std::vector<double> SparseStateRewardParser::parseSparseStateReward(uint_fast64_t stateCount, std::string const & filename) {
+			// Open file.
+			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
+				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+				throw storm::exceptions::WrongFormatException();
+			}
+
+			MappedFile file(filename.c_str());
+			char* buf = file.getData();
+
+			// Create state reward vector with given state count.
+			std::vector<double> stateRewards(stateCount);
+
+			// Now parse state reward assignments.
+			uint_fast64_t state;
+			double reward;
+
+			// Iterate over states.
+			while (buf[0] != '\0') {
+				// Parse state number and reward value.
+				state = checked_strtol(buf, &buf);
+				reward = checked_strtod(buf, &buf);
+				if (reward < 0.0) {
+					LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\".");
+					throw storm::exceptions::WrongFormatException() << "State reward file specifies illegal reward value.";
+				}
+
+				stateRewards[state] = reward;
+
+				buf = trimWhitespaces(buf);
+			}
+			return stateRewards;
 		}
 
-		stateRewards[state] = reward;
-
-		buf = trimWhitespaces(buf);
-	}
-	return stateRewards;
-}
-
-}  // namespace parser
-
+	}  // namespace parser
 }  // namespace storm
diff --git a/src/parser/SparseStateRewardParser.h b/src/parser/SparseStateRewardParser.h
index 2efe0a937..f9e149e83 100644
--- a/src/parser/SparseStateRewardParser.h
+++ b/src/parser/SparseStateRewardParser.h
@@ -6,24 +6,26 @@
 #include <string>
 
 namespace storm {
-
-namespace parser {
-
-/*!
- * A class providing the functionality to parse a the state rewards of a model.
- */
-class SparseStateRewardParser {
-public:
-
-	/*!
-	 *	@brief Load state reward file and return vector of state rewards.
-	 */
-	static std::vector<double> parseSparseStateReward(uint_fast64_t stateCount, std::string const &filename);
-
-};
-
-} // namespace parser
-
+	namespace parser {
+
+		/*!
+		 * A class providing the functionality to parse a the state rewards of a model.
+		 */
+		class SparseStateRewardParser {
+		public:
+
+			/*!
+			 *	Reads a state reward file and puts the result in a state reward vector.
+			 *
+			 *	@param stateCount The number of states.
+			 *	@param filename The path and name of the state reward file.
+			 *	@return The created state reward vector.
+			 */
+			static std::vector<double> parseSparseStateReward(uint_fast64_t stateCount, std::string const &filename);
+
+		};
+
+	} // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_SPARSESTATEREWARDPARSER_H_ */
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index 77af61ef7..e063f1f35 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -26,7 +26,7 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
 	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra";
 
 	// Execute the parser.
-	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
+	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
 
 	// Build the actual transition matrix.
 	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
@@ -103,7 +103,7 @@ TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
 	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespace_input_01.tra";
 
 	// Execute the parser.
-	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
+	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
 
 	// Build the actual transition matrix.
 	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));

From 07465f604a0330fb520fbf8a52c234a58f0fc969 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Mon, 10 Feb 2014 18:26:12 +0100
Subject: [PATCH 015/147] Refactored and added to the test for the
 AtomicPropositionLabelParser.

Former-commit-id: 8cae0fd9dfd5e293517d212e012e771f793dbae1
---
 .../AtomicPropositionLabelingParser.cpp       |  18 ++-
 test/functional/parser/AutoParserTest.cpp     |  29 ++++
 test/functional/parser/LabFileParserTest.cpp  | 136 ++++++++++++++++++
 test/functional/parser/ReadLabFileTest.cpp    |  92 ------------
 4 files changed, 179 insertions(+), 96 deletions(-)
 create mode 100644 test/functional/parser/AutoParserTest.cpp
 create mode 100644 test/functional/parser/LabFileParserTest.cpp
 delete mode 100644 test/functional/parser/ReadLabFileTest.cpp

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index f56cbb025..b77a67af4 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -122,15 +122,19 @@ namespace storm {
 			// We want to skip it.
 			buf += 4;
 
-			uint_fast64_t node;
+			// Now eliminate remaining whitespaces such as empty lines and start parsing.
+			buf = trimWhitespaces(buf);
+
+			uint_fast64_t state;
 			cnt = 0;
 
 			// Now parse the assignments of labels to nodes.
 			while (buf[0] != '\0') {
 
-				// Parse the node number and iterate over its labels (atomic propositions).
+				// Parse the state number and iterate over its labels (atomic propositions).
 				// Stop at the end of the line.
-				node = checked_strtol(buf, &buf);
+				state = checked_strtol(buf, &buf);
+
 				while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
 					cnt = skipWord(buf) - buf;
 					if (cnt == 0) {
@@ -145,7 +149,13 @@ namespace storm {
 						// Copy the label to the buffer, null terminate it and add it to labeling.
 						strncpy(proposition, buf, cnt);
 						proposition[cnt] = '\0';
-						labeling.addAtomicPropositionToState(proposition, node);
+
+						// Has the label been declared in the header?
+						if(!labeling.containsAtomicProposition(proposition)) {
+							LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition" << proposition << " was found but not declared.");
+							throw storm::exceptions::WrongFormatException();
+						}
+						labeling.addAtomicPropositionToState(proposition, state);
 						buf += cnt;
 					}
 				}
diff --git a/test/functional/parser/AutoParserTest.cpp b/test/functional/parser/AutoParserTest.cpp
new file mode 100644
index 000000000..d79edd70a
--- /dev/null
+++ b/test/functional/parser/AutoParserTest.cpp
@@ -0,0 +1,29 @@
+/*
+ * AutoParserTest.cpp
+ *
+ *  Created on: Feb 10, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include "src/parser/AutoParser.h"
+#include "src/exceptions/FileIoException.h"
+
+TEST(AutoParserTest, NonExistingFile) {
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
+TEST(AutoParserTest, BasicParsing) {
+
+}
+
+TEST(AutoParserTest, Whitespaces) {
+
+}
+
+TEST(AutoParserTest, Decision) {
+
+}
diff --git a/test/functional/parser/LabFileParserTest.cpp b/test/functional/parser/LabFileParserTest.cpp
new file mode 100644
index 000000000..fb236682d
--- /dev/null
+++ b/test/functional/parser/LabFileParserTest.cpp
@@ -0,0 +1,136 @@
+/*
+ * LabFileParserTest.cpp
+ *
+ *  Created on: 12.09.2012
+ *      Author: Thomas Heinemann
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+#include "src/models/AtomicPropositionsLabeling.h"
+#include "src/parser/AtomicPropositionLabelingParser.h"
+#include "src/exceptions/FileIoException.h"
+#include "src/exceptions/WrongFormatException.h"
+#include "src/exceptions/OutOfRangeException.h"
+
+#include <memory>
+
+TEST(LabFileParserTest, NonExistingFile) {
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
+TEST(LabFileParserTest, BasicParsing) {
+	// This test is based on a test case from the original MRMC.
+	
+	// Parsing the file
+	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
+
+	// Checking whether all propositions are in the labelling
+
+	char phi[] = "phi", psi[] = "psi", smth[] = "smth";
+
+	ASSERT_TRUE(labeling.containsAtomicProposition(phi));
+	ASSERT_TRUE(labeling.containsAtomicProposition(psi));
+	ASSERT_TRUE(labeling.containsAtomicProposition(smth));
+
+	// Testing whether all and only the correct nodes are labeled with "phi"
+	ASSERT_TRUE(labeling.getStateHasAtomicProposition(phi,0));
+	ASSERT_TRUE(labeling.getStateHasAtomicProposition(phi,1));
+	ASSERT_TRUE(labeling.getStateHasAtomicProposition(phi,2));
+
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,3));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,4));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,5));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,6));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,7));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,8));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,9));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,10));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,11));
+
+	//Testing whether all and only the correct nodes are labeled with "psi"
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,0));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,1));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,2));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,3));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,4));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,5));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,6));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,7));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,8));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,9));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,10));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,11));
+
+	//Testing whether all and only the correct nodes are labeled with "smth"
+	ASSERT_TRUE(labeling.getStateHasAtomicProposition(smth,2));
+
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,0));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,1));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,3));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,4));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,5));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,6));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,7));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,8));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,9));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,10));
+	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,11));
+}
+
+TEST(LabFileParserTest, NoDeclarationTagHeader) {
+	// No #DECLARATION tag in file
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/noDeclarationTag.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(LabFileParserTest, NoEndTagHeader) {
+	// No #END tag in file.
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/noEndTag.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(LabFileParserTest, MisspelledDeclarationTagHeader) {
+	// The #DECLARATION tag is misspelled.
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/declarationMisspell.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(LabFileParserTest, MisspelledEndTagHeader) {
+	// The #END tag is misspelled.
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/endMisspell.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(LabFileParserTest, NoLabelDeclaredNoneGiven) {
+	// No label between #DECLARATION and #END and no labels given.
+	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/noLabelsDecNoneGiven.lab");
+	ASSERT_EQ(labeling.getNumberOfAtomicPropositions(), 0);
+	for(uint_fast64_t i = 0; i < 13; i++) {
+		ASSERT_TRUE(labeling.getPropositionsForState(i).empty());
+	}
+}
+
+TEST(LabFileParserTest, UndeclaredLabelsGiven) {
+	// Undeclared labels given.
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/undeclaredLabelsGiven.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(LabFileParserTest, LabelForNonExistentState) {
+	// The index of one of the state that are to be labeled is higher than the number of states in the model.
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/labelForNonexistentState.lab"), storm::exceptions::OutOfRangeException);
+}
+
+TEST(LabFileParserTest, WrongProposition) {
+   // Swapped the state index and the label at one entry.
+   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/swappedStateAndProposition.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(LabFileParserTest, Whitespaces) {
+	// Different configurations of allowed whitespaces are tested.
+
+	// First parse the labeling file without added whitespaces and obtain the hash of its parsed representation.
+	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/withoutWhitespaces.lab");
+	uint_fast64_t correctHash = labeling.getHash();
+
+	// Now parse the labeling file with the added whitespaces and compare the hashes.
+	labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/withWhitespaces.lab");
+	ASSERT_EQ(correctHash, labeling.getHash());
+}
diff --git a/test/functional/parser/ReadLabFileTest.cpp b/test/functional/parser/ReadLabFileTest.cpp
deleted file mode 100644
index 8c0a31b89..000000000
--- a/test/functional/parser/ReadLabFileTest.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * ReadLabFileTest.cpp
- *
- *  Created on: 12.09.2012
- *      Author: Thomas Heinemann
- */
-
-#include "gtest/gtest.h"
-#include "storm-config.h"
-#include "src/models/AtomicPropositionsLabeling.h"
-#include "src/parser/AtomicPropositionLabelingParser.h"
-#include "src/exceptions/FileIoException.h"
-#include "src/exceptions/WrongFormatException.h"
-
-#include <memory>
-
-TEST(ReadLabFileTest, NonExistingFileTest) {
-   // No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
-}
-
-TEST(ReadLabFileTest, ParseTest) {
-	// This test is based on a test case from the original MRMC.
-	
-	// Parsing the file
-	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
-
-	// Checking whether all propositions are in the labelling
-
-	char phi[] = "phi", psi[] = "psi", smth[] = "smth";
-
-	ASSERT_TRUE(labeling.containsAtomicProposition(phi));
-	ASSERT_TRUE(labeling.containsAtomicProposition(psi));
-	ASSERT_TRUE(labeling.containsAtomicProposition(smth));
-
-	// Testing whether all and only the correct nodes are labeled with "phi"
-	ASSERT_TRUE(labeling.getStateHasAtomicProposition(phi,0));
-	ASSERT_TRUE(labeling.getStateHasAtomicProposition(phi,1));
-	ASSERT_TRUE(labeling.getStateHasAtomicProposition(phi,2));
-
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,3));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,4));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,5));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,6));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,7));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,8));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,9));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,10));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(phi,11));
-
-	//Testing whether all and only the correct nodes are labeled with "psi"
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,0));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,1));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,2));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,3));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,4));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,5));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,6));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,7));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,8));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,9));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,10));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(psi,11));
-
-	//Testing whether all and only the correct nodes are labeled with "smth"
-	ASSERT_TRUE(labeling.getStateHasAtomicProposition(smth,2));
-
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,0));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,1));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,3));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,4));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,5));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,6));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,7));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,8));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,9));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,10));
-	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,11));
-}
-
-TEST(ReadLabFileTest, WrongHeaderTest1) {
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException);
-}
-
-TEST(ReadLabFileTest, WrongHeaderTest2) {
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException);
-}
-
-TEST(ReadLabFileTest, WrongPropositionTest) {
-   ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException);
-}
-

From df2e65b667eeda49109aa5d50ea82f02e3ac355f Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 26 Feb 2014 13:19:07 +0100
Subject: [PATCH 016/147] Added a test for the AutoParser.

Former-commit-id: a51f3af6534e63d9376d69d3320a040392f4c4d9
---
 .../DeterministicSparseTransitionParser.cpp   |  7 ---
 test/functional/parser/AutoParserTest.cpp     | 49 +++++++++++++++++++
 2 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 883908a53..b302f68a6 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -122,13 +122,6 @@ namespace storm {
 						col = checked_strtol(buf, &buf);
 						val = checked_strtod(buf, &buf);
 
-						// Read probability of this transition.
-						// Check, if the value is a probability, i.e. if it is between 0 and 1.
-						if ((val < 0.0) || (val > 1.0)) {
-							LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
-							throw storm::exceptions::WrongFormatException();
-						}
-
 						// Test if we moved to a new row.
 						// Handle all incomplete or skipped rows.
 						if (lastRow != row) {
diff --git a/test/functional/parser/AutoParserTest.cpp b/test/functional/parser/AutoParserTest.cpp
index d79edd70a..cbd322f87 100644
--- a/test/functional/parser/AutoParserTest.cpp
+++ b/test/functional/parser/AutoParserTest.cpp
@@ -10,6 +10,7 @@
 
 #include "src/parser/AutoParser.h"
 #include "src/exceptions/FileIoException.h"
+#include "src/exceptions/WrongFormatException.h"
 
 TEST(AutoParserTest, NonExistingFile) {
 	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
@@ -17,13 +18,61 @@ TEST(AutoParserTest, NonExistingFile) {
 }
 
 TEST(AutoParserTest, BasicParsing) {
+	// Parse model, which is a Dtmc.
+	std::shared_ptr<storm::models::AbstractModel<double>> modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 
+	// Test if parsed correctly.
+	ASSERT_EQ(modelPtr->getType(), storm::models::DTMC);
+	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
+	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 32);
+	ASSERT_EQ(modelPtr->getInitialStates().getNumberOfSetBits(), 1);
+	ASSERT_TRUE(modelPtr->hasAtomicProposition("three"));
+	ASSERT_FALSE(modelPtr->hasStateRewards());
+	ASSERT_FALSE(modelPtr->hasTransitionRewards());
 }
 
 TEST(AutoParserTest, Whitespaces) {
+	// Test different whitespace combinations by comparing the hash of the model parsed from files without whitespaces with the hash of the models parsed from files with whitespaces.
+	uint_fast64_t correctHash = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab")->getHash();
 
+	ASSERT_EQ(correctHash, storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmcWhitespaces1.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab")->getHash());
+	ASSERT_EQ(correctHash, storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmcWhitespaces2.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab")->getHash());
+}
+
+TEST(AutoParserTest, WrongHint) {
+	// The hint given describes the content but does not conform to the format.
+	ASSERT_THROW(storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/wrongHint.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab"), storm::exceptions::WrongFormatException);
+}
+
+TEST(AutoParserTest, NoHint) {
+	// There is no hint contained in the given file, so the parser cannot decide which kind of model it is.
+	ASSERT_THROW(storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/noHint.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab"), storm::exceptions::WrongFormatException);
 }
 
 TEST(AutoParserTest, Decision) {
+	// Test if the AutoParser recognizes each model kind and correctly parses it.
+
+	// Dtmc
+	std::shared_ptr<storm::models::AbstractModel<double>> modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
+	ASSERT_EQ(modelPtr->getType(), storm::models::DTMC);
+	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
+	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 32);
+
+	// Ctmc
+	modelPtr.reset();
+	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ctmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
+	ASSERT_EQ(modelPtr->getType(), storm::models::CTMC);
+	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
+	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 31);
+
+	// Mdp
+	modelPtr.reset();
+	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/mdp.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
+	ASSERT_EQ(modelPtr->getType(), storm::models::MDP);
+	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
+	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 36);
+
+	// Ctmdp
 
+	// MA
 }

From fc45cdb238e4a51d7bf713bf5bb5d7f14a1f558c Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 26 Feb 2014 17:15:23 +0100
Subject: [PATCH 017/147] Added tests for deterministic models i.e.
 DeterministicModelParserTest and DeterministicSparseTransitionParserTest

- Additionally lots of small changes to other tests and test files.


Former-commit-id: d0b3f968ea72562b320f1932c2d011d1feafb6a3
---
 .../MarkovAutomatonSparseTransitionParser.cpp |  10 +-
 test/functional/parser/AutoParserTest.cpp     |  13 +
 .../parser/DeterministicModelParserTest.cpp   | 101 ++++++++
 ...eterministicSparseTransitionParserTest.cpp | 229 ++++++++++++++++++
 test/functional/parser/LabFileParserTest.cpp  |   8 +
 ...ovAutomatonSparseTransitionParserTest.cpp} |  72 +++---
 6 files changed, 385 insertions(+), 48 deletions(-)
 create mode 100644 test/functional/parser/DeterministicModelParserTest.cpp
 create mode 100644 test/functional/parser/DeterministicSparseTransitionParserTest.cpp
 rename test/functional/parser/{MarkovAutomatonParserTest.cpp => MarkovAutomatonSparseTransitionParserTest.cpp} (77%)

diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 775792897..78cc5c978 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -124,9 +124,13 @@ namespace storm {
 
 						// And the corresponding probability/rate.
 						double val = checked_strtod(buf, &buf);
-						if (val <= 0.0) {
-							LOG4CPLUS_ERROR(logger, "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
-							throw storm::exceptions::WrongFormatException() << "Illegal probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
+						if (val < 0.0) {
+							LOG4CPLUS_ERROR(logger, "Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
+							throw storm::exceptions::WrongFormatException() << "Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
+						}
+						if (!isMarkovianChoice && val > 1.0) {
+							LOG4CPLUS_ERROR(logger, "Illegal probability value for transition from " << source << " to " << target << ": " << val << ".");
+							throw storm::exceptions::WrongFormatException() << "Illegal probability value for transition from " << source << " to " << target << ": " << val << ".";
 						}
 
 						// We need to record that we found at least one successor state for the current choice.
diff --git a/test/functional/parser/AutoParserTest.cpp b/test/functional/parser/AutoParserTest.cpp
index cbd322f87..a9a15a228 100644
--- a/test/functional/parser/AutoParserTest.cpp
+++ b/test/functional/parser/AutoParserTest.cpp
@@ -73,6 +73,19 @@ TEST(AutoParserTest, Decision) {
 	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 36);
 
 	// Ctmdp
+	// Note: For now we use the Mdp from above just given the ctmdp hint, since the implementation of the Ctmdp model seems not Quite right yet.
+	//       We still do this test so that the code responsible for Ctmdps is executed at least once during testing.
+	// TODO: Fix the Ctmdp implementation and use an actual Ctmdp for testing.
+	modelPtr.reset();
+	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ctmdp.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
+	ASSERT_EQ(modelPtr->getType(), storm::models::CTMDP);
+	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
+	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 36);
 
 	// MA
+	modelPtr.reset();
+	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ma.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
+	ASSERT_EQ(modelPtr->getType(), storm::models::MA);
+	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
+	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 35);
 }
diff --git a/test/functional/parser/DeterministicModelParserTest.cpp b/test/functional/parser/DeterministicModelParserTest.cpp
new file mode 100644
index 000000000..2e5ddfa16
--- /dev/null
+++ b/test/functional/parser/DeterministicModelParserTest.cpp
@@ -0,0 +1,101 @@
+/*
+ * DeterministicModelParserTest.cpp
+ *
+ *  Created on: Feb 24, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include "src/parser/DeterministicModelParser.h"
+#include "src/models/Dtmc.h"
+#include "src/models/Ctmc.h"
+#include "src/exceptions/FileIoException.h"
+
+TEST(DeterministicModelParserTest, NonExistingFile) {
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseCtmc(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
+TEST(DeterministicModelParserTest, BasicDtmcParsing) {
+
+	// Parse a Dtmc and check the result.
+	storm::models::Dtmc<double> dtmc(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew"));
+
+	ASSERT_EQ(dtmc.getNumberOfStates(), 8);
+	ASSERT_EQ(dtmc.getNumberOfTransitions(), 21);
+
+	ASSERT_EQ(dtmc.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_TRUE(dtmc.getInitialStates().get(0));
+	ASSERT_TRUE(dtmc.getInitialStates().get(7));
+	ASSERT_EQ(dtmc.getStateLabeling().getNumberOfAtomicPropositions(), 5);
+	ASSERT_EQ(dtmc.getLabelsForState(6).size(), 2);
+
+	ASSERT_TRUE(dtmc.hasStateRewards());
+	ASSERT_EQ(dtmc.getStateRewardVector()[7], 42);
+	double rewardSum = 0;
+	for(uint_fast64_t i = 0; i < dtmc.getStateRewardVector().size(); i++) {
+		rewardSum += dtmc.getStateRewardVector()[i];
+	}
+	ASSERT_EQ(rewardSum, 263.32);
+
+	ASSERT_TRUE(dtmc.hasTransitionRewards());
+	ASSERT_EQ(dtmc.getTransitionRewardMatrix().getEntryCount(), 17);
+	rewardSum = 0;
+	for(uint_fast64_t i = 0; i < dtmc.getTransitionRewardMatrix().getRowCount(); i++) {
+			rewardSum += dtmc.getTransitionRewardMatrix().getRowSum(i);
+	}
+	ASSERT_EQ(rewardSum, 125.4);
+}
+
+
+TEST(DeterministicModelParserTest, BasicCtmcParsing) {
+
+	// Parse a Ctmc and check the result.
+	storm::models::Ctmc<double> ctmc(storm::parser::DeterministicModelParser::parseCtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew"));
+
+	ASSERT_EQ(ctmc.getNumberOfStates(), 8);
+	ASSERT_EQ(ctmc.getNumberOfTransitions(), 21);
+
+	ASSERT_EQ(ctmc.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_TRUE(ctmc.getInitialStates().get(0));
+	ASSERT_TRUE(ctmc.getInitialStates().get(7));
+	ASSERT_EQ(ctmc.getStateLabeling().getNumberOfAtomicPropositions(), 5);
+	ASSERT_EQ(ctmc.getLabelsForState(6).size(), 2);
+
+	ASSERT_TRUE(ctmc.hasStateRewards());
+	ASSERT_EQ(ctmc.getStateRewardVector()[7], 42);
+	double rewardSum = 0;
+	for(uint_fast64_t i = 0; i < ctmc.getStateRewardVector().size(); i++) {
+		rewardSum += ctmc.getStateRewardVector()[i];
+	}
+	ASSERT_EQ(rewardSum, 263.32);
+
+	ASSERT_TRUE(ctmc.hasTransitionRewards());
+	ASSERT_EQ(ctmc.getTransitionRewardMatrix().getEntryCount(), 17);
+	rewardSum = 0;
+	for(uint_fast64_t i = 0; i < ctmc.getTransitionRewardMatrix().getRowCount(); i++) {
+			rewardSum += ctmc.getTransitionRewardMatrix().getRowSum(i);
+	}
+	ASSERT_EQ(rewardSum, 125.4);
+}
+
+TEST(DeterministicModelParserTest, UnmatchedFiles) {
+
+	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
+
+	// The labeling file contains a label for a non existent state.
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general_input.lab"), storm::exceptions::OutOfRangeException);
+
+	// The state reward file contains a reward for a non existent state.
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.state.rew"), storm::exceptions::OutOfRangeException);
+
+	// The transition reward file contains rewards for a non existent state.
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew"), storm::exceptions::OutOfRangeException);
+
+	// The transition reward file contains rewards for a non existent transition
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_unmatched.trans.rew"), storm::exceptions::OutOfRangeException);
+}
diff --git a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
new file mode 100644
index 000000000..0c4b528b0
--- /dev/null
+++ b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
@@ -0,0 +1,229 @@
+/*
+ * DeterministicSparseTransitionParserTest.cpp
+ *
+ *  Created on: Feb 24, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include "src/parser/DeterministicSparseTransitionParser.h"
+#include "src/storage/SparseMatrix.h"
+#include "src/settings/InternalOptionMemento.h"
+#include "src/exceptions/FileIoException.h"
+#include "src/exceptions/WrongFormatException.h"
+
+TEST(DeterministicSparseTransitionParserTest, NonExistingFile) {
+
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+
+	storm::storage::SparseMatrix<double> nullMatrix;
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", nullMatrix), storm::exceptions::FileIoException);
+}
+
+
+TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
+
+	// Parse a deterministic transitions file and test the resulting matrix.
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra");
+
+	ASSERT_EQ(transitionMatrix.getColumnCount(), 8);
+	ASSERT_EQ(transitionMatrix.getEntryCount(), 21);
+
+	// Test every entry of the matrix.
+	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
+
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 0);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 0);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.4);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.4);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 0.7);
+	cIter++;
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 0.9);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 0.224653);
+	cIter++;
+	ASSERT_EQ(cIter->first, 7);
+	ASSERT_EQ(cIter->second, 0.775347);
+}
+
+TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
+
+	// First parse a transition file. Then parse a transition reward file for the resulting transitiion matrix.
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra");
+
+	storm::storage::SparseMatrix<double> rewardMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew", transitionMatrix);
+
+	ASSERT_EQ(rewardMatrix.getColumnCount(), 8);
+	ASSERT_EQ(rewardMatrix.getEntryCount(), 17);
+
+	// Test every entry of the matrix.
+	storm::storage::SparseMatrix<double>::const_iterator cIter = rewardMatrix.begin(0);
+
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 10);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 5.5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 21.4);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 4);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 1.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 9.5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 6.7);
+	cIter++;
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 12);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 35.224653);
+	cIter++;
+	ASSERT_EQ(cIter->first, 7);
+	ASSERT_EQ(cIter->second, 9.875347);
+}
+
+
+TEST(DeterministicSparseTransitionParserTest, Whitespaces) {
+
+	// Test the resilience of the parser against whitespaces.
+	// Do so by comparing the hash of the matrix resulting from the file without whitespaces with the hash of the matrix resulting from the file with whitespaces.
+	uint_fast64_t correctHash = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra").hash();
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_whitespaces_input.tra");
+	ASSERT_EQ(correctHash, transitionMatrix.hash());
+
+	// Do the same for the corresponding transition rewards file (with and without whitespaces)
+	correctHash = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew", transitionMatrix).hash();
+	ASSERT_EQ(correctHash, storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_whitespaces_input.trans.rew", transitionMatrix).hash());
+}
+
+TEST(DeterministicSparseTransitionParserTest, MixedTransitionOrder) {
+
+	// Since the MatrixBuilder needs sequential input of new elements reordering of transitions or states should throw an exception.
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedTransitionOrder_input.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedStateOrder_input.tra"), storm::exceptions::InvalidArgumentException);
+
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra");
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedTransitionOrder_input.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedStateOrder_input.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
+}
+
+TEST(DeterministicSparseTransitionParserTest, FixDeadlocks) {
+
+	// Set the fixDeadlocks flag temporarily. It is set to its old value once the deadlockOption object is destructed.
+	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
+
+	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock_input.tra");
+
+	ASSERT_EQ(transitionMatrix.getColumnCount(), 9);
+	ASSERT_EQ(transitionMatrix.getEntryCount(), 23);
+
+	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(7);
+	ASSERT_EQ(cIter->first, 7);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 6);
+	ASSERT_EQ(cIter->second, 0.224653);
+	cIter++;
+	ASSERT_EQ(cIter->first, 7);
+	ASSERT_EQ(cIter->second, 0.775347);
+	cIter++;
+	ASSERT_EQ(cIter->first, 8);
+	ASSERT_EQ(cIter->second, 0);
+}
+
+TEST(DeterministicSparseTransitionParserTest, DontFixDeadlocks) {
+
+	// Try to parse a transitions file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
+	storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
+
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock_input.tra"), storm::exceptions::WrongFormatException);
+}
+
+TEST(DeterministicSparseTransitionParserTest, DoubledLines) {
+	// There is a redundant line in the transition file. As the transition already exists this should throw an exception.
+	// Note: If two consecutive lines are doubled no exception is thrown.
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_doubledLines_input.tra"), storm::exceptions::InvalidArgumentException);
+}
diff --git a/test/functional/parser/LabFileParserTest.cpp b/test/functional/parser/LabFileParserTest.cpp
index fb236682d..0b4d58c28 100644
--- a/test/functional/parser/LabFileParserTest.cpp
+++ b/test/functional/parser/LabFileParserTest.cpp
@@ -118,6 +118,14 @@ TEST(LabFileParserTest, LabelForNonExistentState) {
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/labelForNonexistentState.lab"), storm::exceptions::OutOfRangeException);
 }
 
+// Note: As implemented at the moment, each label given for a state in any line is set to true for that state (logical or over all lines for that state).
+// This behavior might not be ideal as multiple lines for one state are not necessary and might indicate a corrupt or wrong file.
+TEST(LabFileParserTest, DoubledLines) {
+	// There are multiple lines attributing labels to the same state.
+	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/doubledLines.lab");
+	ASSERT_EQ(labeling.getPropositionsForState(1).size(), 3);
+}
+
 TEST(LabFileParserTest, WrongProposition) {
    // Swapped the state index and the label at one entry.
    ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/swappedStateAndProposition.lab"), storm::exceptions::WrongFormatException);
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
similarity index 77%
rename from test/functional/parser/MarkovAutomatonParserTest.cpp
rename to test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
index e063f1f35..bb8f4102b 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
@@ -16,11 +16,13 @@
 #include "src/parser/SparseStateRewardParser.h"
 #include "src/utility/cstring.h"
 #include "src/parser/MarkovAutomatonParser.h"
+#include "src/settings/InternalOptionMemento.h"
+#include "src/exceptions/WrongFormatException.h"
 
 #define STATE_COUNT 6
 #define CHOICE_COUNT 7
 
-TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
+TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 
 	// The file that will be used for the test.
 	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra";
@@ -98,9 +100,9 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
 	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
 
-TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
+TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
 	// The file that will be used for the test.
-	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespace_input_01.tra";
+	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespaces_input.tra";
 
 	// Execute the parser.
 	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
@@ -175,50 +177,30 @@ TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
 	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
 
-//TODO: Deadlock Test. I am quite sure that the deadlock state handling does not behave quite right.
-//                     Find a way to test this by manipulating the fixDeadlocks flag of the settings.
+TEST(MarkovAutomatonSparseTransitionParserTest, FixDeadlocks) {
+	// Set the fixDeadlocks flag temporarily. It is set to its old value once the deadlockOption object is destructed.
+	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
 
-/*
-TEST(MarkovAutomatonSparseTransitionParserTest, DeadlockTest) {
-	// Save the fixDeadlocks flag, since it will be manipulated during the test.
-	bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
-	storm::settings::Settings::getInstance()->set("fixDeadlocks");
-
-
-	// The file that will be used for the test.
-	std::string filename = "/functional/parser/tra_files/ma_general_input_01.tra";
-
-	storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
-
-	// Test if the result of the first pass has been transfered correctly
-	ASSERT_EQ(result.transitionMatrix.colCount, 7);
-	ASSERT_EQ(result.transitionMatrix.nonZeroEntryCount, 8);
-	ASSERT_EQ(result.markovianChoices.getNumberOfSetBits(), 2);
-
-	// Test the general structure of the transition system (that will be an Markov automaton).
-	//TODO
+	// Parse a Markov Automaton transition file with the fixDeadlocks Flag set and test if it works.
+	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock_input.tra");
 
-	//Do the test again but this time without the fixDeadlock flag. This should throw an exception.
-	storm::settings::Settings::getInstance()->unset("fixDeadlocks");
-
-	bool thrown = false;
-
-	try {
-		// Parse the file, again.
-		result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
-	} catch(Exception &exception) {
-		// Print the exception and remember that it was thrown.
-		exception.print(std::cout);
-		thrown = true;
-	}
+	// Test if the result is consistent with the parsed Markov Automaton.
+	storm::storage::SparseMatrix<double> resultMatrix(result.transitionMatrixBuilder.build(0,0));
+	ASSERT_EQ(resultMatrix.getColumnCount(), STATE_COUNT + 1);
+	ASSERT_EQ(resultMatrix.getEntryCount(), 13);
+	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT +1);
+	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT +1);
+	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
+	ASSERT_EQ(result.exitRates.size(), STATE_COUNT + 1);
+	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 8);
+}
 
-	ASSERT_TRUE(thrown);
+TEST(MarkovAutomatonSparseTransitionParserTest, DontFixDeadlocks) {
+	// Try to parse a Markov Automaton transition file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
+	storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
 
-	// Reset the fixDeadlocks flag to its original value.
-	if(fixDeadlocks) {
-		storm::settings::Settings::getInstance()->set("fixDeadlocks");
-	}
-}*/
+	ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock_input.tra"), storm::exceptions::WrongFormatException);
+}
 
 double round(double val, int precision)
 {
@@ -228,7 +210,7 @@ double round(double val, int precision)
     return val;
 }
 
-TEST(SparseStateRewardParserTest, BasicParseTest) {
+TEST(SparseStateRewardParserTest, BasicParsing) {
 
 	// Get the parsing result.
 	std::vector<double> result = storm::parser::SparseStateRewardParser::parseSparseStateReward(100, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_basic.state.rew");
@@ -239,7 +221,7 @@ TEST(SparseStateRewardParserTest, BasicParseTest) {
 	}
 }
 
-TEST(MarkovAutomatonParserTest, BasicParseTest) {
+TEST(MarkovAutomatonParserTest, BasicParsing) {
 
 	// Get the parsing result.
 	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input_01.state.rew", "");

From 5318d9254a535cc1b47f21d35e4f76b9070475f2 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Thu, 27 Feb 2014 00:01:23 +0100
Subject: [PATCH 018/147] Refactured the MarkovAutomatonParser tests, added to
 them and split them into two files.

- Also prepared files for the NondeterministicModelPArser tests.


Former-commit-id: f8909e2ef526036e5333e115f8caa406e34c4c2a
---
 src/parser/MarkovAutomatonParser.h            |  2 +-
 .../MarkovAutomatonSparseTransitionParser.cpp |  3 +-
 src/parser/SparseStateRewardParser.cpp        |  7 +-
 test/functional/parser/MappedFileTest.cpp     | 46 ++++++++++++
 .../parser/MarkovAutomatonParserTest.cpp      | 71 +++++++++++++++++++
 ...kovAutomatonSparseTransitionParserTest.cpp | 43 ++---------
 .../NondeterministicModelParserTest.cpp       | 31 ++++++++
 ...eterministicSparseTransitionParserTest.cpp | 49 +++++++++++++
 test/functional/parser/ParseMdpTest.cpp       | 25 -------
 .../parser/StateRewardParserTest.cpp          | 32 +++++++++
 test/functional/parser/testStringFile.txt     |  1 +
 11 files changed, 246 insertions(+), 64 deletions(-)
 create mode 100644 test/functional/parser/MappedFileTest.cpp
 create mode 100644 test/functional/parser/MarkovAutomatonParserTest.cpp
 create mode 100644 test/functional/parser/NondeterministicModelParserTest.cpp
 create mode 100644 test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
 delete mode 100644 test/functional/parser/ParseMdpTest.cpp
 create mode 100644 test/functional/parser/StateRewardParserTest.cpp
 create mode 100644 test/functional/parser/testStringFile.txt

diff --git a/src/parser/MarkovAutomatonParser.h b/src/parser/MarkovAutomatonParser.h
index 6f3ea5d01..19dcbafd0 100644
--- a/src/parser/MarkovAutomatonParser.h
+++ b/src/parser/MarkovAutomatonParser.h
@@ -28,7 +28,7 @@ namespace storm {
 			 * @param transitionRewardFilename The name of the file that contains the transition rewards of the Markov automaton. This should be empty as transition rewards are not supported by Markov Automata.
 			 * @return The parsed MarkovAutomaton.
 			 */
-			static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename, std::string const& transitionRewardFilename);
+			static storm::models::MarkovAutomaton<double> parseMarkovAutomaton(std::string const& transitionsFilename, std::string const& labelingFilename, std::string const& stateRewardFilename = "", std::string const& transitionRewardFilename = "");
 		};
 
 	} // namespace parser
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 78cc5c978..10682dc04 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -2,6 +2,7 @@
 
 #include "src/settings/Settings.h"
 #include "src/exceptions/WrongFormatException.h"
+#include "src/exceptions/FileIoException.h"
 #include "src/parser/MappedFile.h"
 #include "src/utility/cstring.h"
 
@@ -263,7 +264,7 @@ namespace storm {
 
 			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-				throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
+				throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
 			}
 
 			// Open file and prepare pointer to buffer.
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index ad4d815de..9827a7ed7 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -8,6 +8,7 @@
 #include "src/parser/SparseStateRewardParser.h"
 
 #include "src/exceptions/WrongFormatException.h"
+#include "src/exceptions/OutOfRangeException.h"
 #include "src/utility/cstring.h"
 #include "src/parser/MappedFile.h"
 #include "log4cplus/logger.h"
@@ -23,7 +24,7 @@ namespace storm {
 			// Open file.
 			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-				throw storm::exceptions::WrongFormatException();
+				throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
 			}
 
 			MappedFile file(filename.c_str());
@@ -40,6 +41,10 @@ namespace storm {
 			while (buf[0] != '\0') {
 				// Parse state number and reward value.
 				state = checked_strtol(buf, &buf);
+				if(stateCount <= state) {
+					LOG4CPLUS_ERROR(logger, "Found reward for a state of an invalid index \"" << state << "\". The model has only " << stateCount << " states.");
+					throw storm::exceptions::OutOfRangeException() << "Found reward for a state of an invalid index \"" << state << "\"";
+				}
 				reward = checked_strtod(buf, &buf);
 				if (reward < 0.0) {
 					LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\".");
diff --git a/test/functional/parser/MappedFileTest.cpp b/test/functional/parser/MappedFileTest.cpp
new file mode 100644
index 000000000..f63632362
--- /dev/null
+++ b/test/functional/parser/MappedFileTest.cpp
@@ -0,0 +1,46 @@
+/*
+ * MappedFileTest.cpp
+ *
+ *  Created on: Feb 25, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include <string>
+#include "src/parser/MappedFile.h"
+#include "src/exceptions/FileIoException.h"
+
+TEST(MappedFileTest, NonExistingFile) {
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::MappedFile(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
+TEST(MappedFileTest, BasicFunctionality) {
+
+	// Open a file and test if the content is loaded as expected.
+	storm::parser::MappedFile file(STORM_CPP_TESTS_BASE_PATH "/functional/parser/testStringFile.txt");
+	std::string testString = "This is a test string.\n";
+	ASSERT_EQ(file.getDataEnd() - file.getData(), testString.length());
+	char const * testStringPtr = testString.c_str();
+	for(char* dataPtr = file.getData(); dataPtr < file.getDataEnd(); dataPtr++) {
+		ASSERT_EQ(*dataPtr, *testStringPtr);
+		testStringPtr++;
+	}
+}
+
+TEST(MappedFileTest, ExistsAndReadble) {
+
+	// Test the fileExistsAndIsReadable() method under various circumstances.
+
+	// File exists and is readable.
+	ASSERT_TRUE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_CPP_TESTS_BASE_PATH "/functional/parser/testStringFile.txt"));
+
+	// File does not exist.
+	ASSERT_FALSE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"));
+
+	// File exists but is not readable.
+	// TODO: Find portable solution to providing a situation in which a file exists but is not readable.
+	//ASSERT_FALSE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_CPP_TESTS_BASE_PATH "/functional/parser/unreadableFile.txt"));
+}
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
new file mode 100644
index 000000000..5be7e32e4
--- /dev/null
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -0,0 +1,71 @@
+/*
+ * MarkovAutomatonParserTest.cpp
+ *
+ *  Created on: 25.02.2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include "src/parser/MarkovAutomatonParser.h"
+#include "src/exceptions/FileIoException.h"
+
+TEST(MarkovAutomatonParserTest, NonExistingFile) {
+
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
+TEST(MarkovAutomatonParserTest, BasicParsing) {
+
+	// Get the parsing result.
+	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input_01.state.rew");
+
+	// Test sizes and counts.
+	ASSERT_EQ(result.getNumberOfStates(), 6);
+	ASSERT_EQ(result.getNumberOfChoices(), 7);
+	ASSERT_EQ(result.getNumberOfTransitions(), 12);
+
+	// Test the exit rates. These have to be 0 for all non-Markovian states.
+	std::vector<double> rates = result.getExitRates();
+	ASSERT_EQ(result.getExitRate(0), 2);
+	ASSERT_FALSE(result.isMarkovianState(1));
+	ASSERT_EQ(result.getExitRate(1), 0);
+	ASSERT_EQ(result.getExitRate(2), 15);
+	ASSERT_FALSE(result.isMarkovianState(3));
+	ASSERT_EQ(result.getExitRate(3), 0);
+	ASSERT_FALSE(result.isMarkovianState(4));
+	ASSERT_EQ(result.getExitRate(4), 0);
+	ASSERT_FALSE(result.isMarkovianState(5));
+	ASSERT_EQ(result.getExitRate(5), 0);
+
+	// Test the labeling.
+	ASSERT_EQ(result.getStateLabeling().getNumberOfAtomicPropositions(), 3);
+	ASSERT_EQ(result.getInitialStates().getNumberOfSetBits(), 1);
+	ASSERT_EQ(result.getLabelsForState(4).size(), 0);
+	ASSERT_EQ(result.getStateLabeling().getLabeledStates("goal").getNumberOfSetBits(), 1);
+
+	// Test the state rewards.
+	ASSERT_TRUE(result.hasStateRewards());
+	double rewardSum = 0;
+	for(uint_fast64_t i = 0; i < result.getStateRewardVector().size(); i++) {
+		rewardSum += result.getStateRewardVector()[i];
+	}
+	ASSERT_EQ(rewardSum, 1015.765099984);
+	ASSERT_EQ(result.getStateRewardVector()[0], 0);
+
+	// Test the transition rewards.
+	ASSERT_FALSE(result.hasTransitionRewards());
+}
+
+TEST(MarkovAutomatonParserTest, UnmatchedFiles) {
+
+	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
+
+	// The labeling file contains a label for a non existent state.
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_unmatched.lab"), storm::exceptions::OutOfRangeException);
+
+	// The state reward file contains a reward for a non existent state.
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_unmatched.state.rew"), storm::exceptions::OutOfRangeException);
+}
diff --git a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
index bb8f4102b..30d84c5e0 100644
--- a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
@@ -9,19 +9,24 @@
 #include "storm-config.h"
 #include "src/settings/Settings.h"
 
-#include <cmath>
 #include <vector>
 
 #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
-#include "src/parser/SparseStateRewardParser.h"
 #include "src/utility/cstring.h"
 #include "src/parser/MarkovAutomatonParser.h"
 #include "src/settings/InternalOptionMemento.h"
 #include "src/exceptions/WrongFormatException.h"
+#include "src/exceptions/FileIoException.h"
 
 #define STATE_COUNT 6
 #define CHOICE_COUNT 7
 
+TEST(MarkovAutomatonSparseTransitionParserTest, NonExistingFile) {
+
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
 TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 
 	// The file that will be used for the test.
@@ -201,37 +206,3 @@ TEST(MarkovAutomatonSparseTransitionParserTest, DontFixDeadlocks) {
 
 	ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock_input.tra"), storm::exceptions::WrongFormatException);
 }
-
-double round(double val, int precision)
-{
-    std::stringstream s;
-    s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
-    s >> val;
-    return val;
-}
-
-TEST(SparseStateRewardParserTest, BasicParsing) {
-
-	// Get the parsing result.
-	std::vector<double> result = storm::parser::SparseStateRewardParser::parseSparseStateReward(100, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_basic.state.rew");
-
-	// Now test if the correct value were parsed.
-	for(int i = 0; i < 100; i++) {
-		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
-	}
-}
-
-TEST(MarkovAutomatonParserTest, BasicParsing) {
-
-	// Get the parsing result.
-	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input_01.state.rew", "");
-
-	// Test sizes and counts.
-	ASSERT_EQ(result.getNumberOfStates(), STATE_COUNT);
-	ASSERT_EQ(result.getNumberOfChoices(), CHOICE_COUNT);
-	ASSERT_EQ(result.getNumberOfTransitions(), 12);
-
-	// Test
-	std::vector<double> rates = result.getExitRates();
-	ASSERT_EQ(rates[0], 2);
-}
diff --git a/test/functional/parser/NondeterministicModelParserTest.cpp b/test/functional/parser/NondeterministicModelParserTest.cpp
new file mode 100644
index 000000000..b9740adcb
--- /dev/null
+++ b/test/functional/parser/NondeterministicModelParserTest.cpp
@@ -0,0 +1,31 @@
+/*
+ * NondeterministicModelParserTest.cpp
+ *
+ *  Created on: Feb 26, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include "src/parser/NondeterministicModelParser.h"
+#include "src/models/Mdp.h"
+#include "src/models/Ctmdp.h"
+#include "src/exceptions/FileIoException.h"
+
+TEST(NondeterministicModelParserTest, NonExistingFile) {
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+}
+
+TEST(NondeterministicModelParserTest, BasicMdpParsing) {
+
+}
+
+
+TEST(NondeterministicModelParserTest, BasicCtmdpParsing) {
+
+}
+
+TEST(NondeterministicModelParserTest, UnmatchedFiles) {
+
+}
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
new file mode 100644
index 000000000..7f2b3b866
--- /dev/null
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -0,0 +1,49 @@
+/*
+ * NondeterministicSparseTransitionParserTest.cpp
+ *
+ *  Created on: Feb 26, 2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include "src/parser/NondeterministicSparseTransitionParser.h"
+#include "src/storage/SparseMatrix.h"
+#include "src/settings/InternalOptionMemento.h"
+#include "src/exceptions/FileIoException.h"
+#include "src/exceptions/WrongFormatException.h"
+
+TEST(NondeterministicSparseTransitionParserTest, NonExistingFile) {
+
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+}
+
+
+TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
+
+}
+
+TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
+
+}
+
+TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
+
+}
+
+TEST(NondeterministicSparseTransitionParserTest, MixedTransitionOrder) {
+
+}
+
+TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
+
+}
+
+TEST(NondeterministicSparseTransitionParserTest, DontFixDeadlocks) {
+
+}
+
+TEST(NondeterministicSparseTransitionParserTest, DoubledLines) {
+
+}
diff --git a/test/functional/parser/ParseMdpTest.cpp b/test/functional/parser/ParseMdpTest.cpp
deleted file mode 100644
index ff447488d..000000000
--- a/test/functional/parser/ParseMdpTest.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * ParseMdpTest.cpp
- *
- *  Created on: 14.01.2013
- *      Author: Thomas Heinemann
- */
-
-
-#include "gtest/gtest.h"
-#include "storm-config.h"
-#include "src/parser/NondeterministicModelParser.h"
-
-TEST(ParseMdpTest, parseAndOutput) {
-	storm::models::Mdp<double> mdp = storm::parser::NondeterministicModelParser::parseMdp(
-		STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input_01.tra",
-		STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
-	storm::storage::SparseMatrix<double> const& matrix = mdp.getTransitionMatrix();
-
-	ASSERT_EQ(mdp.getNumberOfStates(), (uint_fast64_t)3);
-	ASSERT_EQ(mdp.getNumberOfTransitions(), (uint_fast64_t)11);
-	ASSERT_EQ(matrix.getRowCount(), (uint_fast64_t)(2 * 3));
-	ASSERT_EQ(matrix.getColumnCount(), (uint_fast64_t)3);
-}
-
-
diff --git a/test/functional/parser/StateRewardParserTest.cpp b/test/functional/parser/StateRewardParserTest.cpp
new file mode 100644
index 000000000..aea2e80c0
--- /dev/null
+++ b/test/functional/parser/StateRewardParserTest.cpp
@@ -0,0 +1,32 @@
+/*
+ * MarkovAutomatonParserTest.cpp
+ *
+ *  Created on: 26.02.2014
+ *      Author: Manuel Sascha Weiand
+ */
+
+#include "gtest/gtest.h"
+#include "storm-config.h"
+
+#include <cmath>
+
+#include "src/parser/SparseStateRewardParser.h"
+
+double round(double val, int precision)
+{
+    std::stringstream s;
+    s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
+    s >> val;
+    return val;
+}
+
+TEST(SparseStateRewardParserTest, BasicParsing) {
+
+	// Get the parsing result.
+	std::vector<double> result = storm::parser::SparseStateRewardParser::parseSparseStateReward(100, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_basic.state.rew");
+
+	// Now test if the correct value were parsed.
+	for(int i = 0; i < 100; i++) {
+		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
+	}
+}
diff --git a/test/functional/parser/testStringFile.txt b/test/functional/parser/testStringFile.txt
new file mode 100644
index 000000000..fe200f008
--- /dev/null
+++ b/test/functional/parser/testStringFile.txt
@@ -0,0 +1 @@
+This is a test string.

From 77fe1e1bda1913717279ef63704b209a624f33f0 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Thu, 27 Feb 2014 04:31:30 +0100
Subject: [PATCH 019/147] Added NondeterministcModelParser tests and
 SparseStateRewardParser tests.

- Done with the tests. At least for now.
|- There are tests for all parsers and helper classes now.

Next up: Some minor fixes and finally the merge.


Former-commit-id: ebb2ea50d53c0289a5806f7f00d4ec1b52d2f16e
---
 ...NondeterministicSparseTransitionParser.cpp |  83 ++++---
 .../parser/MarkovAutomatonParserTest.cpp      |   4 +-
 .../NondeterministicModelParserTest.cpp       |  72 ++++++
 ...eterministicSparseTransitionParserTest.cpp | 213 +++++++++++++++++-
 ...st.cpp => SparseStateRewardParserTest.cpp} |  19 +-
 5 files changed, 353 insertions(+), 38 deletions(-)
 rename test/functional/parser/{StateRewardParserTest.cpp => SparseStateRewardParserTest.cpp} (50%)

diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 6dc1ffbc2..05e4c4a81 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -12,6 +12,7 @@
 #include "src/parser/MappedFile.h"
 #include "src/settings/Settings.h"
 #include "src/exceptions/FileIoException.h"
+#include "src/exceptions/OutOfRangeException.h"
 #include "src/exceptions/WrongFormatException.h"
 
 #include "src/utility/cstring.h"
@@ -44,7 +45,7 @@ namespace storm {
 
 			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-				throw storm::exceptions::WrongFormatException();
+				throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
 			}
 
 			// Open file.
@@ -57,7 +58,7 @@ namespace storm {
 			// If first pass returned zero, the file format was wrong.
 			if (firstPass.numberOfNonzeroEntries == 0) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format.");
-				throw storm::exceptions::WrongFormatException();
+				throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": erroneous file format.";
 			}
 
 			// Perform second pass.
@@ -73,16 +74,18 @@ namespace storm {
 				// The reward matrix should match the size of the transition matrix.
 				if (firstPass.choices > modelInformation.transitionMatrix.getRowCount() || (uint_fast64_t)(firstPass.highestStateIndex + 1) > modelInformation.transitionMatrix.getColumnCount()) {
 					LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size.");
-					throw storm::exceptions::WrongFormatException() << "Reward matrix size exceeds transition matrix size.";
+					throw storm::exceptions::OutOfRangeException() << "Reward matrix size exceeds transition matrix size.";
 				} else if (firstPass.choices != modelInformation.transitionMatrix.getRowCount()) {
 					LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count.");
-					throw storm::exceptions::WrongFormatException() << "Reward matrix row count does not match transition matrix row count.";
+					throw storm::exceptions::OutOfRangeException() << "Reward matrix row count does not match transition matrix row count.";
+				} else if(firstPass.numberOfNonzeroEntries > modelInformation.transitionMatrix.getEntryCount()) {
+					LOG4CPLUS_ERROR(logger, "The reward matrix has more entries than the transition matrix. There must be a reward for a non existent transition");
+					throw storm::exceptions::OutOfRangeException() << "The reward matrix has more entries than the transition matrix.";
 				} else {
 					firstPass.highestStateIndex = modelInformation.transitionMatrix.getColumnCount() - 1;
 				}
 			}
 
-
 			// Create the matrix builder.
 			// The matrix to be build should have as many columns as we have nodes and as many rows as we have choices.
 			// Those two values, as well as the number of nonzero elements, was been calculated in the first run.
@@ -93,7 +96,7 @@ namespace storm {
 			std::vector<uint_fast64_t> rowMapping(firstPass.highestStateIndex + 2, 0);
 
 			// Initialize variables for the parsing run.
-			uint_fast64_t source = 0, target = 0, lastsource = 0, choice = 0, lastchoice = 0, curRow = 0;
+			uint_fast64_t source = 0, target = 0, lastSource = 0, choice = 0, lastChoice = 0, curRow = 0;
 			double val = 0.0;
 			bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 			bool hadDeadlocks = false;
@@ -108,33 +111,33 @@ namespace storm {
 				if (isRewardFile) {
 					// If we have switched the source state, we possibly need to insert the rows of the last
 					// source state.
-					if (source != lastsource) {
-						curRow += ((modelInformation.rowMapping)[lastsource + 1] - (modelInformation.rowMapping)[lastsource]) -(lastchoice + 1);
+					if (source != lastSource) {
+						curRow += ((modelInformation.rowMapping)[lastSource + 1] - (modelInformation.rowMapping)[lastSource]) -(lastChoice + 1);
 					}
 
 					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 					// choices.
-					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
+					for (uint_fast64_t i = lastSource + 1; i < source; ++i) {
 						curRow += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
 					}
 
 					// If we advanced to the next state, but skipped some choices, we have to reserve rows
 					// for them
-					if (source != lastsource) {
+					if (source != lastSource) {
 						curRow += choice + 1;
-					} else if (choice != lastchoice) {
-						curRow += choice - lastchoice;
+					} else if (choice != lastChoice) {
+						curRow += choice - lastChoice;
 					}
 				} else {
 					// Increase line count if we have either finished reading the transitions of a certain state
 					// or we have finished reading one nondeterministic choice of a state.
-					if ((source != lastsource || choice != lastchoice)) {
+					if ((source != lastSource || choice != lastChoice)) {
 						++curRow;
 					}
 					// Check if we have skipped any source node, i.e. if any node has no
 					// outgoing transitions. If so, insert a self-loop.
 					// Also add self-loops to rowMapping.
-					for (uint_fast64_t node = lastsource + 1; node < source; node++) {
+					for (uint_fast64_t node = lastSource + 1; node < source; node++) {
 						hadDeadlocks = true;
 						if (fixDeadlocks) {
 							rowMapping.at(node) = curRow;
@@ -145,7 +148,7 @@ namespace storm {
 							LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": node " << node << " has no outgoing transitions.");
 						}
 					}
-					if (source != lastsource) {
+					if (source != lastSource) {
 						// Add this source to rowMapping, if this is the first choice we encounter for this state.
 						rowMapping.at(source) = curRow;
 					}
@@ -156,8 +159,8 @@ namespace storm {
 				val = checked_strtod(buf, &buf);
 				matrixBuilder.addNextValue(curRow, target, val);
 
-				lastsource = source;
-				lastchoice = choice;
+				lastSource = source;
+				lastChoice = choice;
 
 				// Proceed to beginning of next line in file and next row in matrix.
 				buf = forwardToLineEnd(buf);
@@ -165,7 +168,7 @@ namespace storm {
 				buf = trimWhitespaces(buf);
 			}
 
-			for (uint_fast64_t node = lastsource + 1; node <= firstPass.highestStateIndex + 1; node++) {
+			for (uint_fast64_t node = lastSource + 1; node <= firstPass.highestStateIndex + 1; node++) {
 				rowMapping.at(node) = curRow + 1;
 			}
 
@@ -186,7 +189,7 @@ namespace storm {
 			}
 
 			// Read all transitions.
-			uint_fast64_t source = 0, target = 0, choice = 0, lastchoice = 0, lastsource = 0;
+			uint_fast64_t source = 0, target = 0, choice = 0, lastChoice = 0, lastSource = 0;
 			double val = 0.0;
 			NondeterministicSparseTransitionParser::FirstPassResult result;
 
@@ -201,6 +204,11 @@ namespace storm {
 				// Read the name of the nondeterministic choice.
 				choice = checked_strtol(buf, &buf);
 
+				if (source < lastSource) {
+					LOG4CPLUS_ERROR(logger, "The current source state " << source << " is smaller than the last one " << lastSource << ".");
+					throw storm::exceptions::InvalidArgumentException() << "The current source state " << source << " is smaller than the last one " << lastSource << ".";
+				}
+
 				// Check if we encountered a state index that is bigger than all previously seen.
 				if (source > result.highestStateIndex) {
 					result.highestStateIndex = source;
@@ -209,32 +217,34 @@ namespace storm {
 				if (isRewardFile) {
 					// If we have switched the source state, we possibly need to insert rows for skipped choices of the last
 					// source state.
-					if (source != lastsource) {
+					if (source != lastSource) {
 						// number of choices skipped = number of choices of last state - number of choices read
-						result.choices += ((modelInformation.rowMapping)[lastsource + 1] - (modelInformation.rowMapping)[lastsource]) - (lastchoice + 1);
+						result.choices += ((modelInformation.rowMapping)[lastSource + 1] - (modelInformation.rowMapping)[lastSource]) - (lastChoice + 1);
 					}
 
 					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 					// choices.
-					for (uint_fast64_t i = lastsource + 1; i < source; ++i) {
+					for (uint_fast64_t i = lastSource + 1; i < source; ++i) {
 						result.choices += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
 					}
 
 					// If we advanced to the next state, but skipped some choices, we have to reserve rows
 					// for them.
-					if (source != lastsource) {
+					if (source != lastSource) {
 						result.choices += choice + 1;
-					} else if (choice != lastchoice) {
-						result.choices += choice - lastchoice;
+					} else if (choice != lastChoice) {
+						result.choices += choice - lastChoice;
 					}
 				} else {
 
 					// If we have skipped some states, we need to reserve the space for the self-loop insertion
 					// in the second pass.
-					if (source > lastsource + 1) {
-						result.numberOfNonzeroEntries += source - lastsource - 1;
-						result.choices += source - lastsource - 1;
-					} else if (source != lastsource || choice != lastchoice) {
+					if (source > lastSource + 1) {
+						result.numberOfNonzeroEntries += source - lastSource - 1;
+						result.choices += source - lastSource - 1;
+					}
+
+					if (source != lastSource || choice != lastChoice) {
 						// If we have switched the source state or the nondeterministic choice, we need to
 						// reserve one row more.
 						++result.choices;
@@ -250,14 +260,19 @@ namespace storm {
 
 				// Read value and check whether it's positive.
 				val = checked_strtod(buf, &buf);
-				if ((val < 0.0) || (val > 1.0)) {
+				if (!isRewardFile && (val < 0.0 || val > 1.0 )) {
 					LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
 					NondeterministicSparseTransitionParser::FirstPassResult nullResult;
 					return nullResult;
 				}
+				else if (val < 0.0) {
+					LOG4CPLUS_ERROR(logger, "Expected a positive reward value but got \"" << std::string(buf, 0, 16) << "\".");
+					NondeterministicSparseTransitionParser::FirstPassResult nullResult;
+					return nullResult;
+				}
 
-				lastchoice = choice;
-				lastsource = source;
+				lastChoice = choice;
+				lastSource = source;
 
 				// Increase number of non-zero values.
 				result.numberOfNonzeroEntries++;
@@ -271,11 +286,11 @@ namespace storm {
 
 			if (isRewardFile) {
 				// If not all rows were filled for the last state, we need to insert them.
-				result.choices += ((modelInformation.rowMapping)[lastsource + 1] - (modelInformation.rowMapping)[lastsource] ) - (lastchoice + 1);
+				result.choices += ((modelInformation.rowMapping)[lastSource + 1] - (modelInformation.rowMapping)[lastSource] ) - (lastChoice + 1);
 
 				// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 				// choices.
-				for (uint_fast64_t i = lastsource + 1; i < modelInformation.rowMapping.size() - 1; ++i) {
+				for (uint_fast64_t i = lastSource + 1; i < modelInformation.rowMapping.size() - 1; ++i) {
 					result.choices += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
 				}
 			}
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index 5be7e32e4..9e257d36a 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -20,7 +20,7 @@ TEST(MarkovAutomatonParserTest, NonExistingFile) {
 TEST(MarkovAutomatonParserTest, BasicParsing) {
 
 	// Get the parsing result.
-	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input_01.state.rew");
+	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input.state.rew");
 
 	// Test sizes and counts.
 	ASSERT_EQ(result.getNumberOfStates(), 6);
@@ -67,5 +67,5 @@ TEST(MarkovAutomatonParserTest, UnmatchedFiles) {
 	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_unmatched.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_unmatched.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_unmatched.state.rew"), storm::exceptions::OutOfRangeException);
 }
diff --git a/test/functional/parser/NondeterministicModelParserTest.cpp b/test/functional/parser/NondeterministicModelParserTest.cpp
index b9740adcb..e327777e2 100644
--- a/test/functional/parser/NondeterministicModelParserTest.cpp
+++ b/test/functional/parser/NondeterministicModelParserTest.cpp
@@ -15,17 +15,89 @@
 
 TEST(NondeterministicModelParserTest, NonExistingFile) {
 	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseCtmdp(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
 }
 
 TEST(NondeterministicModelParserTest, BasicMdpParsing) {
 
+	// Parse a Mdp and check the result.
+	storm::models::Mdp<double> mdp(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew"));
+
+	ASSERT_EQ(mdp.getNumberOfStates(), 6);
+	ASSERT_EQ(mdp.getNumberOfTransitions(), 22);
+	ASSERT_EQ(mdp.getNumberOfChoices(), 11);
+
+	ASSERT_EQ(mdp.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_TRUE(mdp.getInitialStates().get(0));
+	ASSERT_TRUE(mdp.getInitialStates().get(4));
+	ASSERT_EQ(mdp.getStateLabeling().getNumberOfAtomicPropositions(), 4);
+	ASSERT_EQ(mdp.getLabelsForState(0).size(), 3);
+
+	ASSERT_TRUE(mdp.hasStateRewards());
+	ASSERT_EQ(mdp.getStateRewardVector()[0], 0);
+	ASSERT_EQ(mdp.getStateRewardVector()[4], 42);
+	double rewardSum = 0;
+	for(uint_fast64_t i = 0; i < mdp.getStateRewardVector().size(); i++) {
+		rewardSum += mdp.getStateRewardVector()[i];
+	}
+	ASSERT_EQ(rewardSum, 158.32);
+
+	ASSERT_TRUE(mdp.hasTransitionRewards());
+	ASSERT_EQ(mdp.getTransitionRewardMatrix().getEntryCount(), 17);
+	rewardSum = 0;
+	for(uint_fast64_t i = 0; i < mdp.getTransitionRewardMatrix().getRowCount(); i++) {
+			rewardSum += mdp.getTransitionRewardMatrix().getRowSum(i);
+	}
+	ASSERT_EQ(rewardSum, 1376.864);
 }
 
 
 TEST(NondeterministicModelParserTest, BasicCtmdpParsing) {
+	// Parse a Ctmdp and check the result.
+	storm::models::Ctmdp<double> ctmdp(storm::parser::NondeterministicModelParser::parseCtmdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew"));
+
+	ASSERT_EQ(ctmdp.getNumberOfStates(), 6);
+	ASSERT_EQ(ctmdp.getNumberOfTransitions(), 22);
+	ASSERT_EQ(ctmdp.getNumberOfChoices(), 11);
 
+	ASSERT_EQ(ctmdp.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_TRUE(ctmdp.getInitialStates().get(0));
+	ASSERT_TRUE(ctmdp.getInitialStates().get(4));
+	ASSERT_EQ(ctmdp.getStateLabeling().getNumberOfAtomicPropositions(), 4);
+	ASSERT_EQ(ctmdp.getLabelsForState(0).size(), 3);
+
+	ASSERT_TRUE(ctmdp.hasStateRewards());
+	ASSERT_EQ(ctmdp.getStateRewardVector()[0], 0);
+	ASSERT_EQ(ctmdp.getStateRewardVector()[4], 42);
+	double rewardSum = 0;
+	for(uint_fast64_t i = 0; i < ctmdp.getStateRewardVector().size(); i++) {
+		rewardSum += ctmdp.getStateRewardVector()[i];
+	}
+	ASSERT_EQ(rewardSum, 158.32);
+
+	ASSERT_TRUE(ctmdp.hasTransitionRewards());
+	ASSERT_EQ(ctmdp.getTransitionRewardMatrix().getEntryCount(), 17);
+	rewardSum = 0;
+	for(uint_fast64_t i = 0; i < ctmdp.getTransitionRewardMatrix().getRowCount(); i++) {
+			rewardSum += ctmdp.getTransitionRewardMatrix().getRowSum(i);
+	}
+	ASSERT_EQ(rewardSum, 1376.864);
 }
 
 TEST(NondeterministicModelParserTest, UnmatchedFiles) {
+	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
+
+	// The labeling file contains a label for a non existent state.
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general_input.lab"), storm::exceptions::OutOfRangeException);
+
+	// The state reward file contains a reward for a non existent state.
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.state.rew"), storm::exceptions::OutOfRangeException);
+
+	// The transition reward file contains rewards for a non existent state.
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew"), storm::exceptions::OutOfRangeException);
 
+	// The transition reward file contains rewards for a non existent transition
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_unmatched.trans.rew"), storm::exceptions::OutOfRangeException);
 }
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
index 7f2b3b866..554c65df2 100644
--- a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -17,33 +17,244 @@
 TEST(NondeterministicSparseTransitionParserTest, NonExistingFile) {
 
 	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+
+	storm::parser::NondeterministicSparseTransitionParser::Result nullInformation;
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", nullInformation), storm::exceptions::FileIoException);
 }
 
 
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
+	// Parse a nondeterministic transitions file and test the result.
+	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra"));
+
+	// Test the row mapping, i.e. at which row which state starts.
+	ASSERT_EQ(result.rowMapping.size(), 7);
+	ASSERT_EQ(result.rowMapping[0], 0);
+	ASSERT_EQ(result.rowMapping[1], 4);
+	ASSERT_EQ(result.rowMapping[2], 5);
+	ASSERT_EQ(result.rowMapping[3], 7);
+	ASSERT_EQ(result.rowMapping[4], 8);
+	ASSERT_EQ(result.rowMapping[5], 9);
+	ASSERT_EQ(result.rowMapping[6], 11);
+
+	// Test the transition matrix.
+	ASSERT_EQ(result.transitionMatrix.getColumnCount(), 6);
+	ASSERT_EQ(result.transitionMatrix.getRowCount(), 11);
+	ASSERT_EQ(result.transitionMatrix.getEntryCount(), 22);
+
+	// Test every entry of the matrix.
+	storm::storage::SparseMatrix<double>::const_iterator cIter = result.transitionMatrix.begin(0);
+
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 0.9);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.9);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.5);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 0.001);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 0.999);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.7);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.3);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0.6);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 1);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
+	// Parse a nondeterministic transitions file and test the result.
+	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra"));
+	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew", modelInformation).transitionMatrix);
+
+	// Test the transition matrix.
+	ASSERT_EQ(result.getColumnCount(), 6);
+	ASSERT_EQ(result.getRowCount(), 11);
+	ASSERT_EQ(result.getEntryCount(), 17);
+
+	// Test every entry of the matrix.
+	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
 
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 30);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 15.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 75);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 2.45);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 0);
+	ASSERT_EQ(cIter->second, 0.114);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 90);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 55);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 87);
+	cIter++;
+	ASSERT_EQ(cIter->first, 2);
+	ASSERT_EQ(cIter->second, 13);
+	cIter++;
+	ASSERT_EQ(cIter->first, 3);
+	ASSERT_EQ(cIter->second, 999);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.7);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.3);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 6);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
+	// Test the resilience of the parser against whitespaces.
+	// Do so by comparing the hashes of the transition matices and the rowMapping vectors element by element.
+	storm::parser::NondeterministicSparseTransitionParser::Result correctResult(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra"));
+	storm::parser::NondeterministicSparseTransitionParser::Result whitespaceResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_whitespaces_input.tra");
+	ASSERT_EQ(correctResult.transitionMatrix.hash(), whitespaceResult.transitionMatrix.hash());
+	ASSERT_EQ(correctResult.rowMapping.size(), whitespaceResult.rowMapping.size());
+	for(uint_fast64_t i = 0; i < correctResult.rowMapping.size(); i++) {
+		ASSERT_EQ(correctResult.rowMapping[i], whitespaceResult.rowMapping[i]);
+	}
 
+	// Do the same (minus the unused rowMapping) for the corresponding transition rewards file (with and without whitespaces)
+	uint_fast64_t correctHash = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew", correctResult).transitionMatrix.hash();
+	ASSERT_EQ(correctHash, storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_whitespaces_input.trans.rew", whitespaceResult).transitionMatrix.hash());
 }
 
 TEST(NondeterministicSparseTransitionParserTest, MixedTransitionOrder) {
+	// Since the MatrixBuilder needs sequential input of new elements reordering of transitions or states should throw an exception.
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedTransitionOrder_input.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedStateOrder_input.tra"), storm::exceptions::InvalidArgumentException);
 
+	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra");
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedTransitionOrder_input.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedStateOrder_input.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
+	// Set the fixDeadlocks flag temporarily. It is set to its old value once the deadlockOption object is destructed.
+	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
+
+	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
+	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock_input.tra"));
+
+	ASSERT_EQ(result.rowMapping.size(), 8);
+	ASSERT_EQ(result.rowMapping[5], 9);
+	ASSERT_EQ(result.rowMapping[6], 10);
+	ASSERT_EQ(result.rowMapping[7], 12);
+
+	ASSERT_EQ(result.transitionMatrix.getColumnCount(), 7);
+	ASSERT_EQ(result.transitionMatrix.getRowCount(), 12);
+	ASSERT_EQ(result.transitionMatrix.getEntryCount(), 23);
+
+	storm::storage::SparseMatrix<double>::const_iterator cIter = result.transitionMatrix.begin(8);
+
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.7);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.3);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 1);
+	cIter++;
+	ASSERT_EQ(cIter->first, 1);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 4);
+	ASSERT_EQ(cIter->second, 0.2);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 0.6);
+	cIter++;
+	ASSERT_EQ(cIter->first, 5);
+	ASSERT_EQ(cIter->second, 1);
 
 }
 
 TEST(NondeterministicSparseTransitionParserTest, DontFixDeadlocks) {
+	// Try to parse a transitions file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
+	storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
 
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock_input.tra"), storm::exceptions::WrongFormatException);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, DoubledLines) {
-
+	// There is a redundant line in the transition file. As the transition already exists this should throw an exception.
+	// Note: If two consecutive lines are doubled no exception is thrown.
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_doubledLines_input.tra"), storm::exceptions::InvalidArgumentException);
 }
diff --git a/test/functional/parser/StateRewardParserTest.cpp b/test/functional/parser/SparseStateRewardParserTest.cpp
similarity index 50%
rename from test/functional/parser/StateRewardParserTest.cpp
rename to test/functional/parser/SparseStateRewardParserTest.cpp
index aea2e80c0..0fc88ed2f 100644
--- a/test/functional/parser/StateRewardParserTest.cpp
+++ b/test/functional/parser/SparseStateRewardParserTest.cpp
@@ -1,5 +1,5 @@
 /*
- * MarkovAutomatonParserTest.cpp
+ * SparseStateRewardParserTest.cpp
  *
  *  Created on: 26.02.2014
  *      Author: Manuel Sascha Weiand
@@ -12,6 +12,12 @@
 
 #include "src/parser/SparseStateRewardParser.h"
 
+TEST(SparseStateRewardParserTest, NonExistingFile) {
+
+	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
+	ASSERT_THROW(storm::parser::SparseStateRewardParser::parseSparseStateReward(42, STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
+}
+
 double round(double val, int precision)
 {
     std::stringstream s;
@@ -30,3 +36,14 @@ TEST(SparseStateRewardParserTest, BasicParsing) {
 		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
 	}
 }
+
+TEST(SparseStateRewardParserTest, Whitespaces) {
+
+	// Get the parsing result.
+	std::vector<double> result = storm::parser::SparseStateRewardParser::parseSparseStateReward(100, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_whitespaces.state.rew");
+
+	// Now test if the correct value were parsed.
+	for(int i = 0; i < 100; i++) {
+		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
+	}
+}

From ff1ba43940920c8955c78ec8a90a119c65f44d63 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Mon, 3 Mar 2014 23:56:11 +0100
Subject: [PATCH 020/147] Lots of renames.

Former-commit-id: 1fb272639635a98e3358a3a8b3d23c5df5b8ea22
---
 src/parser/SparseStateRewardParser.cpp        |  3 +-
 ...> AtomicPropositionLabelingParserTest.cpp} | 32 +++++++++----------
 .../parser/DeterministicModelParserTest.cpp   | 10 +++---
 ...eterministicSparseTransitionParserTest.cpp | 30 ++++++++---------
 .../parser/MarkovAutomatonParserTest.cpp      |  6 ++--
 ...kovAutomatonSparseTransitionParserTest.cpp |  8 ++---
 .../NondeterministicModelParserTest.cpp       | 10 +++---
 ...eterministicSparseTransitionParserTest.cpp | 30 ++++++++---------
 .../parser/SparseStateRewardParserTest.cpp    |  1 +
 9 files changed, 66 insertions(+), 64 deletions(-)
 rename test/functional/parser/{LabFileParserTest.cpp => AtomicPropositionLabelingParserTest.cpp} (89%)

diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index 9827a7ed7..c0e0dd28f 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -9,6 +9,7 @@
 
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/OutOfRangeException.h"
+#include "src/exceptions/FileIoException.h"
 #include "src/utility/cstring.h"
 #include "src/parser/MappedFile.h"
 #include "log4cplus/logger.h"
@@ -24,7 +25,7 @@ namespace storm {
 			// Open file.
 			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
 				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
-				throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
+				throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
 			}
 
 			MappedFile file(filename.c_str());
diff --git a/test/functional/parser/LabFileParserTest.cpp b/test/functional/parser/AtomicPropositionLabelingParserTest.cpp
similarity index 89%
rename from test/functional/parser/LabFileParserTest.cpp
rename to test/functional/parser/AtomicPropositionLabelingParserTest.cpp
index 0b4d58c28..b41cc487b 100644
--- a/test/functional/parser/LabFileParserTest.cpp
+++ b/test/functional/parser/AtomicPropositionLabelingParserTest.cpp
@@ -1,8 +1,8 @@
 /*
- * LabFileParserTest.cpp
+ * AtomicPropositionLabelingParserTest.cpp
  *
- *  Created on: 12.09.2012
- *      Author: Thomas Heinemann
+ *  Created on: 03.03.2014
+ *      Author: Manuel Sascha Weiand
  */
 
 #include "gtest/gtest.h"
@@ -15,16 +15,16 @@
 
 #include <memory>
 
-TEST(LabFileParserTest, NonExistingFile) {
+TEST(AtomicPropositionLabelingParserTest, NonExistingFile) {
 	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
 }
 
-TEST(LabFileParserTest, BasicParsing) {
+TEST(AtomicPropositionLabelingParserTest, BasicParsing) {
 	// This test is based on a test case from the original MRMC.
 	
 	// Parsing the file
-	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
+	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general.lab");
 
 	// Checking whether all propositions are in the labelling
 
@@ -79,27 +79,27 @@ TEST(LabFileParserTest, BasicParsing) {
 	ASSERT_FALSE(labeling.getStateHasAtomicProposition(smth,11));
 }
 
-TEST(LabFileParserTest, NoDeclarationTagHeader) {
+TEST(AtomicPropositionLabelingParserTest, NoDeclarationTagHeader) {
 	// No #DECLARATION tag in file
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/noDeclarationTag.lab"), storm::exceptions::WrongFormatException);
 }
 
-TEST(LabFileParserTest, NoEndTagHeader) {
+TEST(AtomicPropositionLabelingParserTest, NoEndTagHeader) {
 	// No #END tag in file.
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/noEndTag.lab"), storm::exceptions::WrongFormatException);
 }
 
-TEST(LabFileParserTest, MisspelledDeclarationTagHeader) {
+TEST(AtomicPropositionLabelingParserTest, MisspelledDeclarationTagHeader) {
 	// The #DECLARATION tag is misspelled.
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/declarationMisspell.lab"), storm::exceptions::WrongFormatException);
 }
 
-TEST(LabFileParserTest, MisspelledEndTagHeader) {
+TEST(AtomicPropositionLabelingParserTest, MisspelledEndTagHeader) {
 	// The #END tag is misspelled.
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/endMisspell.lab"), storm::exceptions::WrongFormatException);
 }
 
-TEST(LabFileParserTest, NoLabelDeclaredNoneGiven) {
+TEST(AtomicPropositionLabelingParserTest, NoLabelDeclaredNoneGiven) {
 	// No label between #DECLARATION and #END and no labels given.
 	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/noLabelsDecNoneGiven.lab");
 	ASSERT_EQ(labeling.getNumberOfAtomicPropositions(), 0);
@@ -108,30 +108,30 @@ TEST(LabFileParserTest, NoLabelDeclaredNoneGiven) {
 	}
 }
 
-TEST(LabFileParserTest, UndeclaredLabelsGiven) {
+TEST(AtomicPropositionLabelingParserTest, UndeclaredLabelsGiven) {
 	// Undeclared labels given.
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/undeclaredLabelsGiven.lab"), storm::exceptions::WrongFormatException);
 }
 
-TEST(LabFileParserTest, LabelForNonExistentState) {
+TEST(AtomicPropositionLabelingParserTest, LabelForNonExistentState) {
 	// The index of one of the state that are to be labeled is higher than the number of states in the model.
 	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/labelForNonexistentState.lab"), storm::exceptions::OutOfRangeException);
 }
 
 // Note: As implemented at the moment, each label given for a state in any line is set to true for that state (logical or over all lines for that state).
 // This behavior might not be ideal as multiple lines for one state are not necessary and might indicate a corrupt or wrong file.
-TEST(LabFileParserTest, DoubledLines) {
+TEST(AtomicPropositionLabelingParserTest, DoubledLines) {
 	// There are multiple lines attributing labels to the same state.
 	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/doubledLines.lab");
 	ASSERT_EQ(labeling.getPropositionsForState(1).size(), 3);
 }
 
-TEST(LabFileParserTest, WrongProposition) {
+TEST(AtomicPropositionLabelingParserTest, WrongProposition) {
    // Swapped the state index and the label at one entry.
    ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/swappedStateAndProposition.lab"), storm::exceptions::WrongFormatException);
 }
 
-TEST(LabFileParserTest, Whitespaces) {
+TEST(AtomicPropositionLabelingParserTest, Whitespaces) {
 	// Different configurations of allowed whitespaces are tested.
 
 	// First parse the labeling file without added whitespaces and obtain the hash of its parsed representation.
diff --git a/test/functional/parser/DeterministicModelParserTest.cpp b/test/functional/parser/DeterministicModelParserTest.cpp
index 2e5ddfa16..b4acacce7 100644
--- a/test/functional/parser/DeterministicModelParserTest.cpp
+++ b/test/functional/parser/DeterministicModelParserTest.cpp
@@ -23,7 +23,7 @@ TEST(DeterministicModelParserTest, NonExistingFile) {
 TEST(DeterministicModelParserTest, BasicDtmcParsing) {
 
 	// Parse a Dtmc and check the result.
-	storm::models::Dtmc<double> dtmc(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew"));
+	storm::models::Dtmc<double> dtmc(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"));
 
 	ASSERT_EQ(dtmc.getNumberOfStates(), 8);
 	ASSERT_EQ(dtmc.getNumberOfTransitions(), 21);
@@ -55,7 +55,7 @@ TEST(DeterministicModelParserTest, BasicDtmcParsing) {
 TEST(DeterministicModelParserTest, BasicCtmcParsing) {
 
 	// Parse a Ctmc and check the result.
-	storm::models::Ctmc<double> ctmc(storm::parser::DeterministicModelParser::parseCtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew"));
+	storm::models::Ctmc<double> ctmc(storm::parser::DeterministicModelParser::parseCtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"));
 
 	ASSERT_EQ(ctmc.getNumberOfStates(), 8);
 	ASSERT_EQ(ctmc.getNumberOfTransitions(), 21);
@@ -88,13 +88,13 @@ TEST(DeterministicModelParserTest, UnmatchedFiles) {
 	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
 
 	// The labeling file contains a label for a non existent state.
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general_input.lab"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent state.
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent transition
 	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_unmatched.trans.rew"), storm::exceptions::OutOfRangeException);
diff --git a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
index 0c4b528b0..296df6e4f 100644
--- a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
@@ -27,7 +27,7 @@ TEST(DeterministicSparseTransitionParserTest, NonExistingFile) {
 TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
 	// Parse a deterministic transitions file and test the resulting matrix.
-	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra");
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
 
 	ASSERT_EQ(transitionMatrix.getColumnCount(), 8);
 	ASSERT_EQ(transitionMatrix.getEntryCount(), 21);
@@ -102,9 +102,9 @@ TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
 
 	// First parse a transition file. Then parse a transition reward file for the resulting transitiion matrix.
-	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra");
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
 
-	storm::storage::SparseMatrix<double> rewardMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew", transitionMatrix);
+	storm::storage::SparseMatrix<double> rewardMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew", transitionMatrix);
 
 	ASSERT_EQ(rewardMatrix.getColumnCount(), 8);
 	ASSERT_EQ(rewardMatrix.getEntryCount(), 17);
@@ -169,24 +169,24 @@ TEST(DeterministicSparseTransitionParserTest, Whitespaces) {
 
 	// Test the resilience of the parser against whitespaces.
 	// Do so by comparing the hash of the matrix resulting from the file without whitespaces with the hash of the matrix resulting from the file with whitespaces.
-	uint_fast64_t correctHash = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra").hash();
-	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_whitespaces_input.tra");
+	uint_fast64_t correctHash = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra").hash();
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_whitespaces.tra");
 	ASSERT_EQ(correctHash, transitionMatrix.hash());
 
 	// Do the same for the corresponding transition rewards file (with and without whitespaces)
-	correctHash = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general_input.trans.rew", transitionMatrix).hash();
-	ASSERT_EQ(correctHash, storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_whitespaces_input.trans.rew", transitionMatrix).hash());
+	correctHash = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew", transitionMatrix).hash();
+	ASSERT_EQ(correctHash, storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_whitespaces.trans.rew", transitionMatrix).hash());
 }
 
 TEST(DeterministicSparseTransitionParserTest, MixedTransitionOrder) {
 
 	// Since the MatrixBuilder needs sequential input of new elements reordering of transitions or states should throw an exception.
-	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedTransitionOrder_input.tra"), storm::exceptions::InvalidArgumentException);
-	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedStateOrder_input.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedTransitionOrder.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedStateOrder.tra"), storm::exceptions::InvalidArgumentException);
 
-	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general_input.tra");
-	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedTransitionOrder_input.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
-	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedStateOrder_input.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedTransitionOrder.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedStateOrder.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
 }
 
 TEST(DeterministicSparseTransitionParserTest, FixDeadlocks) {
@@ -195,7 +195,7 @@ TEST(DeterministicSparseTransitionParserTest, FixDeadlocks) {
 	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
 
 	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
-	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock_input.tra");
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock.tra");
 
 	ASSERT_EQ(transitionMatrix.getColumnCount(), 9);
 	ASSERT_EQ(transitionMatrix.getEntryCount(), 23);
@@ -219,11 +219,11 @@ TEST(DeterministicSparseTransitionParserTest, DontFixDeadlocks) {
 	// Try to parse a transitions file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
 	storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
 
-	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock_input.tra"), storm::exceptions::WrongFormatException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock.tra"), storm::exceptions::WrongFormatException);
 }
 
 TEST(DeterministicSparseTransitionParserTest, DoubledLines) {
 	// There is a redundant line in the transition file. As the transition already exists this should throw an exception.
 	// Note: If two consecutive lines are doubled no exception is thrown.
-	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_doubledLines_input.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_doubledLines.tra"), storm::exceptions::InvalidArgumentException);
 }
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index 9e257d36a..c403e6a22 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -20,7 +20,7 @@ TEST(MarkovAutomatonParserTest, NonExistingFile) {
 TEST(MarkovAutomatonParserTest, BasicParsing) {
 
 	// Get the parsing result.
-	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input.state.rew");
+	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general.state.rew");
 
 	// Test sizes and counts.
 	ASSERT_EQ(result.getNumberOfStates(), 6);
@@ -64,8 +64,8 @@ TEST(MarkovAutomatonParserTest, UnmatchedFiles) {
 	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
 
 	// The labeling file contains a label for a non existent state.
-	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_unmatched.lab"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_unmatched.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_unmatched.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_unmatched.state.rew"), storm::exceptions::OutOfRangeException);
 }
diff --git a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
index 30d84c5e0..f5dcbc1d2 100644
--- a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
@@ -30,7 +30,7 @@ TEST(MarkovAutomatonSparseTransitionParserTest, NonExistingFile) {
 TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 
 	// The file that will be used for the test.
-	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra";
+	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra";
 
 	// Execute the parser.
 	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
@@ -107,7 +107,7 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 
 TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
 	// The file that will be used for the test.
-	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespaces_input.tra";
+	std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespaces.tra";
 
 	// Execute the parser.
 	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
@@ -187,7 +187,7 @@ TEST(MarkovAutomatonSparseTransitionParserTest, FixDeadlocks) {
 	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
 
 	// Parse a Markov Automaton transition file with the fixDeadlocks Flag set and test if it works.
-	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock_input.tra");
+	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock.tra");
 
 	// Test if the result is consistent with the parsed Markov Automaton.
 	storm::storage::SparseMatrix<double> resultMatrix(result.transitionMatrixBuilder.build(0,0));
@@ -204,5 +204,5 @@ TEST(MarkovAutomatonSparseTransitionParserTest, DontFixDeadlocks) {
 	// Try to parse a Markov Automaton transition file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
 	storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
 
-	ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock_input.tra"), storm::exceptions::WrongFormatException);
+	ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock.tra"), storm::exceptions::WrongFormatException);
 }
diff --git a/test/functional/parser/NondeterministicModelParserTest.cpp b/test/functional/parser/NondeterministicModelParserTest.cpp
index e327777e2..0e9e02801 100644
--- a/test/functional/parser/NondeterministicModelParserTest.cpp
+++ b/test/functional/parser/NondeterministicModelParserTest.cpp
@@ -23,7 +23,7 @@ TEST(NondeterministicModelParserTest, NonExistingFile) {
 TEST(NondeterministicModelParserTest, BasicMdpParsing) {
 
 	// Parse a Mdp and check the result.
-	storm::models::Mdp<double> mdp(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew"));
+	storm::models::Mdp<double> mdp(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"));
 
 	ASSERT_EQ(mdp.getNumberOfStates(), 6);
 	ASSERT_EQ(mdp.getNumberOfTransitions(), 22);
@@ -56,7 +56,7 @@ TEST(NondeterministicModelParserTest, BasicMdpParsing) {
 
 TEST(NondeterministicModelParserTest, BasicCtmdpParsing) {
 	// Parse a Ctmdp and check the result.
-	storm::models::Ctmdp<double> ctmdp(storm::parser::NondeterministicModelParser::parseCtmdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general_input.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew"));
+	storm::models::Ctmdp<double> ctmdp(storm::parser::NondeterministicModelParser::parseCtmdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"));
 
 	ASSERT_EQ(ctmdp.getNumberOfStates(), 6);
 	ASSERT_EQ(ctmdp.getNumberOfTransitions(), 22);
@@ -90,13 +90,13 @@ TEST(NondeterministicModelParserTest, UnmatchedFiles) {
 	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
 
 	// The labeling file contains a label for a non existent state.
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general_input.lab"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent state.
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent transition
 	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_unmatched.trans.rew"), storm::exceptions::OutOfRangeException);
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
index 554c65df2..a80442cf1 100644
--- a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -27,7 +27,7 @@ TEST(NondeterministicSparseTransitionParserTest, NonExistingFile) {
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
 	// Parse a nondeterministic transitions file and test the result.
-	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra"));
+	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
 
 	// Test the row mapping, i.e. at which row which state starts.
 	ASSERT_EQ(result.rowMapping.size(), 7);
@@ -116,8 +116,8 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
 	// Parse a nondeterministic transitions file and test the result.
-	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra"));
-	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew", modelInformation).transitionMatrix);
+	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
+	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", modelInformation).transitionMatrix);
 
 	// Test the transition matrix.
 	ASSERT_EQ(result.getColumnCount(), 6);
@@ -182,8 +182,8 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing)
 TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
 	// Test the resilience of the parser against whitespaces.
 	// Do so by comparing the hashes of the transition matices and the rowMapping vectors element by element.
-	storm::parser::NondeterministicSparseTransitionParser::Result correctResult(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra"));
-	storm::parser::NondeterministicSparseTransitionParser::Result whitespaceResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_whitespaces_input.tra");
+	storm::parser::NondeterministicSparseTransitionParser::Result correctResult(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
+	storm::parser::NondeterministicSparseTransitionParser::Result whitespaceResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_whitespaces.tra");
 	ASSERT_EQ(correctResult.transitionMatrix.hash(), whitespaceResult.transitionMatrix.hash());
 	ASSERT_EQ(correctResult.rowMapping.size(), whitespaceResult.rowMapping.size());
 	for(uint_fast64_t i = 0; i < correctResult.rowMapping.size(); i++) {
@@ -191,18 +191,18 @@ TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
 	}
 
 	// Do the same (minus the unused rowMapping) for the corresponding transition rewards file (with and without whitespaces)
-	uint_fast64_t correctHash = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general_input.trans.rew", correctResult).transitionMatrix.hash();
-	ASSERT_EQ(correctHash, storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_whitespaces_input.trans.rew", whitespaceResult).transitionMatrix.hash());
+	uint_fast64_t correctHash = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", correctResult).transitionMatrix.hash();
+	ASSERT_EQ(correctHash, storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_whitespaces.trans.rew", whitespaceResult).transitionMatrix.hash());
 }
 
 TEST(NondeterministicSparseTransitionParserTest, MixedTransitionOrder) {
 	// Since the MatrixBuilder needs sequential input of new elements reordering of transitions or states should throw an exception.
-	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedTransitionOrder_input.tra"), storm::exceptions::InvalidArgumentException);
-	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedStateOrder_input.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedTransitionOrder.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedStateOrder.tra"), storm::exceptions::InvalidArgumentException);
 
-	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general_input.tra");
-	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedTransitionOrder_input.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
-	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedStateOrder_input.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
+	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedTransitionOrder.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedStateOrder.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
@@ -210,7 +210,7 @@ TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
 	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
 
 	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
-	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock_input.tra"));
+	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"));
 
 	ASSERT_EQ(result.rowMapping.size(), 8);
 	ASSERT_EQ(result.rowMapping[5], 9);
@@ -250,11 +250,11 @@ TEST(NondeterministicSparseTransitionParserTest, DontFixDeadlocks) {
 	// Try to parse a transitions file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
 	storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
 
-	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock_input.tra"), storm::exceptions::WrongFormatException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"), storm::exceptions::WrongFormatException);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, DoubledLines) {
 	// There is a redundant line in the transition file. As the transition already exists this should throw an exception.
 	// Note: If two consecutive lines are doubled no exception is thrown.
-	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_doubledLines_input.tra"), storm::exceptions::InvalidArgumentException);
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_doubledLines.tra"), storm::exceptions::InvalidArgumentException);
 }
diff --git a/test/functional/parser/SparseStateRewardParserTest.cpp b/test/functional/parser/SparseStateRewardParserTest.cpp
index 0fc88ed2f..5f9838e93 100644
--- a/test/functional/parser/SparseStateRewardParserTest.cpp
+++ b/test/functional/parser/SparseStateRewardParserTest.cpp
@@ -11,6 +11,7 @@
 #include <cmath>
 
 #include "src/parser/SparseStateRewardParser.h"
+#include "src/exceptions/FileIoException.h"
 
 TEST(SparseStateRewardParserTest, NonExistingFile) {
 

From 6444fc519745b9abcd640f36fa0cc4bcf6b9542c Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 5 Mar 2014 01:55:40 +0100
Subject: [PATCH 021/147] Last fixes and changes.

- Some renaming (among others unmatched -> mismatched).
- Added checks and tests for doubled or skipped lines as well as lines concerning the same transition.

Next up: Remerge.)


Former-commit-id: 05efcbf91c74d710481e9037e9046387d38e63c5
---
 .../AtomicPropositionLabelingParser.cpp       | 10 +++++++-
 .../DeterministicSparseTransitionParser.cpp   | 25 ++++++++++++++++---
 ...NondeterministicSparseTransitionParser.cpp | 24 +++++++++++++++---
 src/parser/SparseStateRewardParser.cpp        | 15 ++++++++++-
 .../AtomicPropositionLabelingParserTest.cpp   |  6 +++--
 .../parser/DeterministicModelParserTest.cpp   | 10 ++++----
 ...eterministicSparseTransitionParserTest.cpp | 12 ++++++++-
 .../parser/MarkovAutomatonParserTest.cpp      |  6 ++---
 .../NondeterministicModelParserTest.cpp       | 10 ++++----
 ...eterministicSparseTransitionParserTest.cpp | 10 +++++++-
 .../parser/SparseStateRewardParserTest.cpp    | 15 +++++++++++
 11 files changed, 116 insertions(+), 27 deletions(-)

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index b77a67af4..43c5d308a 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -125,7 +125,8 @@ namespace storm {
 			// Now eliminate remaining whitespaces such as empty lines and start parsing.
 			buf = trimWhitespaces(buf);
 
-			uint_fast64_t state;
+			uint_fast64_t state = 0;
+			uint_fast64_t lastState = -1;
 			cnt = 0;
 
 			// Now parse the assignments of labels to nodes.
@@ -135,6 +136,12 @@ namespace storm {
 				// Stop at the end of the line.
 				state = checked_strtol(buf, &buf);
 
+				// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
+				if(state <= lastState && lastState != -1) {
+					LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). State " << state << " was found but has already been read or skipped previously.");
+					throw storm::exceptions::WrongFormatException() << "State " << state << " was found but has already been read or skipped previously.";
+				}
+
 				while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
 					cnt = skipWord(buf) - buf;
 					if (cnt == 0) {
@@ -160,6 +167,7 @@ namespace storm {
 					}
 				}
 				buf = trimWhitespaces(buf);
+				lastState = state;
 			}
 
 			return labeling;
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index b302f68a6..67e31484f 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -181,8 +181,16 @@ namespace storm {
 					if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
 				}
 
-				// Finally, build the actual matrix and return it.
-				return resultMatrix.build();
+				// Finally, build the actual matrix, test and return it.
+				storm::storage::SparseMatrix<double> result = resultMatrix.build();
+
+				// Since we cannot do the testing if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
+				if(isRewardFile && !result.isSubmatrixOf(transitionMatrix)) {
+					LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file.");
+					throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file.";
+				}
+
+				return result;
 		}
 
 		DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, bool insertDiagonalEntriesIfMissing) {
@@ -197,7 +205,7 @@ namespace storm {
 			}
 
 			 // Check all transitions for non-zero diagonal entries and deadlock states.
-			uint_fast64_t row, col, lastRow = 0;
+			uint_fast64_t row, col, lastRow = 0, lastCol = -1;
 			bool rowHadDiagonalEntry = false;
 			while (buf[0] != '\0') {
 
@@ -218,7 +226,6 @@ namespace storm {
 						for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
 							++result.numberOfNonzeroEntries;
 						}
-						lastRow = row;
 						rowHadDiagonalEntry = false;
 					}
 
@@ -237,6 +244,16 @@ namespace storm {
 				if (col > result.highestStateIndex) result.highestStateIndex = col;
 
 				++result.numberOfNonzeroEntries;
+
+				// Have we already seen this transition?
+				if (row == lastRow && col == lastCol) {
+					LOG4CPLUS_ERROR(logger, "The same transition (" << row << ", " <<  col << ") is given twice.");
+					throw storm::exceptions::InvalidArgumentException() << "The same transition (" << row << ", " << col << ") is given twice.";
+				}
+
+				lastRow = row;
+				lastCol = col;
+
 				buf = trimWhitespaces(buf);
 			}
 
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 05e4c4a81..6e16b2f43 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -174,7 +174,16 @@ namespace storm {
 
 			if (!fixDeadlocks && hadDeadlocks && !isRewardFile) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
 
-			return NondeterministicSparseTransitionParser::Result(matrixBuilder.build(), rowMapping);
+			// Finally, build the actual matrix, test and return it together with the rowMapping.
+			storm::storage::SparseMatrix<double> resultMatrix = matrixBuilder.build();
+
+			// Since we cannot do the testing if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
+			if(isRewardFile && !resultMatrix.isSubmatrixOf(modelInformation.transitionMatrix)) {
+				LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file.");
+				throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file.";
+			}
+
+			return NondeterministicSparseTransitionParser::Result(resultMatrix, rowMapping);
 		}
 
 		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, bool isRewardFile, Result const & modelInformation) {
@@ -189,7 +198,7 @@ namespace storm {
 			}
 
 			// Read all transitions.
-			uint_fast64_t source = 0, target = 0, choice = 0, lastChoice = 0, lastSource = 0;
+			uint_fast64_t source = 0, target = 0, choice = 0, lastChoice = 0, lastSource = 0, lastTarget = -1;
 			double val = 0.0;
 			NondeterministicSparseTransitionParser::FirstPassResult result;
 
@@ -251,13 +260,19 @@ namespace storm {
 					}
 				}
 
-				// Read target and check if we encountered a state index that is bigger than all previously
-				// seen.
+				// Read target and check if we encountered a state index that is bigger than all previously seen.
 				target = checked_strtol(buf, &buf);
+
 				if (target > result.highestStateIndex) {
 					result.highestStateIndex = target;
 				}
 
+				// Also, have we already seen this transition?
+				if (target == lastTarget && choice == lastChoice && source == lastSource) {
+					LOG4CPLUS_ERROR(logger, "The same transition (" << source << ", " << choice << ", " << target << ") is given twice.");
+					throw storm::exceptions::InvalidArgumentException() << "The same transition (" << source << ", " << choice << ", " << target << ") is given twice.";
+				}
+
 				// Read value and check whether it's positive.
 				val = checked_strtod(buf, &buf);
 				if (!isRewardFile && (val < 0.0 || val > 1.0 )) {
@@ -273,6 +288,7 @@ namespace storm {
 
 				lastChoice = choice;
 				lastSource = source;
+				lastTarget = target;
 
 				// Increase number of non-zero values.
 				result.numberOfNonzeroEntries++;
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index c0e0dd28f..a71d741ad 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -35,18 +35,30 @@ namespace storm {
 			std::vector<double> stateRewards(stateCount);
 
 			// Now parse state reward assignments.
-			uint_fast64_t state;
+			uint_fast64_t state = 0;
+			uint_fast64_t lastState = -1;
 			double reward;
 
 			// Iterate over states.
 			while (buf[0] != '\0') {
+
 				// Parse state number and reward value.
 				state = checked_strtol(buf, &buf);
+
+				// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
+				// Note: The value -1 shows that lastState has not yet been set, i.e. this is the first run of the loop (state index (2^64)-1 is a really bad starting index).
+				if(state <= lastState && lastState != -1) {
+					LOG4CPLUS_ERROR(logger, "State " << state << " was found but has already been read or skipped previously.");
+					throw storm::exceptions::WrongFormatException() << "State " << state << " was found but has already been read or skipped previously.";
+				}
+
 				if(stateCount <= state) {
 					LOG4CPLUS_ERROR(logger, "Found reward for a state of an invalid index \"" << state << "\". The model has only " << stateCount << " states.");
 					throw storm::exceptions::OutOfRangeException() << "Found reward for a state of an invalid index \"" << state << "\"";
 				}
+
 				reward = checked_strtod(buf, &buf);
+
 				if (reward < 0.0) {
 					LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\".");
 					throw storm::exceptions::WrongFormatException() << "State reward file specifies illegal reward value.";
@@ -55,6 +67,7 @@ namespace storm {
 				stateRewards[state] = reward;
 
 				buf = trimWhitespaces(buf);
+				lastState = state;
 			}
 			return stateRewards;
 		}
diff --git a/test/functional/parser/AtomicPropositionLabelingParserTest.cpp b/test/functional/parser/AtomicPropositionLabelingParserTest.cpp
index b41cc487b..538c54936 100644
--- a/test/functional/parser/AtomicPropositionLabelingParserTest.cpp
+++ b/test/functional/parser/AtomicPropositionLabelingParserTest.cpp
@@ -122,8 +122,10 @@ TEST(AtomicPropositionLabelingParserTest, LabelForNonExistentState) {
 // This behavior might not be ideal as multiple lines for one state are not necessary and might indicate a corrupt or wrong file.
 TEST(AtomicPropositionLabelingParserTest, DoubledLines) {
 	// There are multiple lines attributing labels to the same state.
-	storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/doubledLines.lab");
-	ASSERT_EQ(labeling.getPropositionsForState(1).size(), 3);
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/doubledLines.lab"), storm::exceptions::WrongFormatException);
+
+	// There is a line for a state that has been skipped.
+	ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/labParser/doubledLinesSkipped.lab"), storm::exceptions::WrongFormatException);
 }
 
 TEST(AtomicPropositionLabelingParserTest, WrongProposition) {
diff --git a/test/functional/parser/DeterministicModelParserTest.cpp b/test/functional/parser/DeterministicModelParserTest.cpp
index b4acacce7..69f1ff086 100644
--- a/test/functional/parser/DeterministicModelParserTest.cpp
+++ b/test/functional/parser/DeterministicModelParserTest.cpp
@@ -83,19 +83,19 @@ TEST(DeterministicModelParserTest, BasicCtmcParsing) {
 	ASSERT_EQ(rewardSum, 125.4);
 }
 
-TEST(DeterministicModelParserTest, UnmatchedFiles) {
+TEST(DeterministicModelParserTest, MismatchedFiles) {
 
 	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
 
 	// The labeling file contains a label for a non existent state.
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_mismatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent state.
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_mismatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent transition
-	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_unmatched.trans.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_mismatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mismatched.trans.rew"), storm::exceptions::OutOfRangeException);
 }
diff --git a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
index 296df6e4f..0e78f0992 100644
--- a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
@@ -101,7 +101,7 @@ TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
 TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
 
-	// First parse a transition file. Then parse a transition reward file for the resulting transitiion matrix.
+	// First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
 	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
 
 	storm::storage::SparseMatrix<double> rewardMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew", transitionMatrix);
@@ -223,7 +223,17 @@ TEST(DeterministicSparseTransitionParserTest, DontFixDeadlocks) {
 }
 
 TEST(DeterministicSparseTransitionParserTest, DoubledLines) {
+
 	// There is a redundant line in the transition file. As the transition already exists this should throw an exception.
 	// Note: If two consecutive lines are doubled no exception is thrown.
 	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_doubledLines.tra"), storm::exceptions::InvalidArgumentException);
 }
+
+TEST(DeterministicSparseTransitionParserTest, RewardForNonExistentTransition) {
+
+	// First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
+	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
+
+	// There is a reward for a transition that does not exist in the transition matrix.
+	ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_rewardForNonExTrans.trans.rew", transitionMatrix), storm::exceptions::WrongFormatException);
+}
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index c403e6a22..017be55af 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -59,13 +59,13 @@ TEST(MarkovAutomatonParserTest, BasicParsing) {
 	ASSERT_FALSE(result.hasTransitionRewards());
 }
 
-TEST(MarkovAutomatonParserTest, UnmatchedFiles) {
+TEST(MarkovAutomatonParserTest, MismatchedFiles) {
 
 	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
 
 	// The labeling file contains a label for a non existent state.
-	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_unmatched.lab"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_mismatched.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_unmatched.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_mismatched.state.rew"), storm::exceptions::OutOfRangeException);
 }
diff --git a/test/functional/parser/NondeterministicModelParserTest.cpp b/test/functional/parser/NondeterministicModelParserTest.cpp
index 0e9e02801..cf56975b7 100644
--- a/test/functional/parser/NondeterministicModelParserTest.cpp
+++ b/test/functional/parser/NondeterministicModelParserTest.cpp
@@ -86,18 +86,18 @@ TEST(NondeterministicModelParserTest, BasicCtmdpParsing) {
 	ASSERT_EQ(rewardSum, 1376.864);
 }
 
-TEST(NondeterministicModelParserTest, UnmatchedFiles) {
+TEST(NondeterministicModelParserTest, MismatchedFiles) {
 	// Test file combinations that do not match, i.e. differing number of states, transitions, etc.
 
 	// The labeling file contains a label for a non existent state.
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab"), storm::exceptions::OutOfRangeException);
 
 	// The state reward file contains a reward for a non existent state.
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_mismatched.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent state.
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_mismatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"), storm::exceptions::OutOfRangeException);
 
 	// The transition reward file contains rewards for a non existent transition
-	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_unmatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_unmatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_unmatched.trans.rew"), storm::exceptions::OutOfRangeException);
+	ASSERT_THROW(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mismatched.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_mismatched.lab", "", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mismatched.trans.rew"), storm::exceptions::OutOfRangeException);
 }
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
index a80442cf1..8fc55cf1c 100644
--- a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -255,6 +255,14 @@ TEST(NondeterministicSparseTransitionParserTest, DontFixDeadlocks) {
 
 TEST(NondeterministicSparseTransitionParserTest, DoubledLines) {
 	// There is a redundant line in the transition file. As the transition already exists this should throw an exception.
-	// Note: If two consecutive lines are doubled no exception is thrown.
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_doubledLines.tra"), storm::exceptions::InvalidArgumentException);
 }
+
+TEST(NondeterministicSparseTransitionParserTest, RewardForNonExistentTransition) {
+
+	// First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
+	storm::parser::NondeterministicSparseTransitionParser::Result transitionResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
+
+	// There is a reward for a transition that does not exist in the transition matrix.
+	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_rewardForNonExTrans.trans.rew", transitionResult), storm::exceptions::WrongFormatException);
+}
diff --git a/test/functional/parser/SparseStateRewardParserTest.cpp b/test/functional/parser/SparseStateRewardParserTest.cpp
index 5f9838e93..2b6462ca0 100644
--- a/test/functional/parser/SparseStateRewardParserTest.cpp
+++ b/test/functional/parser/SparseStateRewardParserTest.cpp
@@ -12,6 +12,8 @@
 
 #include "src/parser/SparseStateRewardParser.h"
 #include "src/exceptions/FileIoException.h"
+#include "src/exceptions/WrongFormatException.h"
+#include "src/exceptions/OutOfRangeException.h"
 
 TEST(SparseStateRewardParserTest, NonExistingFile) {
 
@@ -48,3 +50,16 @@ TEST(SparseStateRewardParserTest, Whitespaces) {
 		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
 	}
 }
+
+TEST(SparseStateRewardParserTest, DoubledLines) {
+	// There are multiple lines attributing a reward to the same state.
+	ASSERT_THROW(storm::parser::SparseStateRewardParser::parseSparseStateReward(11, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_doubledLines.state.rew"), storm::exceptions::WrongFormatException);
+
+	// There is a line for a state that has been skipped.
+	ASSERT_THROW(storm::parser::SparseStateRewardParser::parseSparseStateReward(11, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_doubledLinesSkipped.state.rew"), storm::exceptions::WrongFormatException);
+}
+
+TEST(SparseStateRewardParserTest, RewardForNonExistentState) {
+	// The index of one of the state that are to be given rewards is higher than the number of states in the model.
+	ASSERT_THROW(storm::parser::SparseStateRewardParser::parseSparseStateReward(99, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_basic.state.rew"), storm::exceptions::OutOfRangeException);
+}

From 28910462ec7b8861424137d220d2509eca4088c3 Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Wed, 12 Mar 2014 22:47:16 +0100
Subject: [PATCH 022/147] Necessary changes to the nondeterministic parses to
 compensate for the change in the way the mapping between states of the model
 and the rows of the transition matrix are handled.

- All tests are green.
- Some comments are now a bit wrong.

Next up: Correct comments.


Former-commit-id: 610c0282b26e11cbe02804fe3daa9b241ed352b1
---
 .../AtomicPropositionLabelingParser.cpp       |  4 +-
 src/parser/MarkovAutomatonParser.cpp          |  8 +-
 .../MarkovAutomatonSparseTransitionParser.cpp | 10 ++-
 .../MarkovAutomatonSparseTransitionParser.h   |  5 +-
 src/parser/NondeterministicModelParser.cpp    | 12 +--
 src/parser/NondeterministicModelParser.h      | 12 +--
 ...NondeterministicSparseTransitionParser.cpp | 73 +++++++++++--------
 .../NondeterministicSparseTransitionParser.h  | 44 +----------
 src/parser/SparseStateRewardParser.cpp        |  4 +-
 ...kovAutomatonSparseTransitionParserTest.cpp | 37 +++++-----
 ...eterministicSparseTransitionParserTest.cpp | 71 +++++++++---------
 11 files changed, 129 insertions(+), 151 deletions(-)

diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index 43c5d308a..0dac9a8c9 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -126,7 +126,7 @@ namespace storm {
 			buf = trimWhitespaces(buf);
 
 			uint_fast64_t state = 0;
-			uint_fast64_t lastState = -1;
+			uint_fast64_t lastState = (uint_fast64_t)-1;
 			cnt = 0;
 
 			// Now parse the assignments of labels to nodes.
@@ -137,7 +137,7 @@ namespace storm {
 				state = checked_strtol(buf, &buf);
 
 				// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
-				if(state <= lastState && lastState != -1) {
+				if(state <= lastState && lastState != (uint_fast64_t)-1) {
 					LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). State " << state << " was found but has already been read or skipped previously.");
 					throw storm::exceptions::WrongFormatException() << "State " << state << " was found but has already been read or skipped previously.";
 				}
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index 91a01c286..707436dab 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -3,6 +3,10 @@
 #include "SparseStateRewardParser.h"
 #include "src/exceptions/WrongFormatException.h"
 
+#include "log4cplus/logger.h"
+#include "log4cplus/loggingmacros.h"
+extern log4cplus::Logger logger;
+
 namespace storm {
 	namespace parser {
 
@@ -12,7 +16,7 @@ namespace storm {
 			storm::parser::MarkovAutomatonSparseTransitionParser::Result transitionResult(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(transitionsFilename));
 
 			// Build the actual transition matrix using the MatrixBuilder provided by the transitionResult.
-			storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0));
+			storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build());
 
 			// Parse the state labeling.
 			storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename));
@@ -30,7 +34,7 @@ namespace storm {
 			}
 
 			// Put the pieces together to generate the Markov Automaton.
-			storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionMatrix), std::move(resultLabeling), std::move(transitionResult.nondeterministicChoiceIndices), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+			storm::models::MarkovAutomaton<double> resultingAutomaton(std::move(transitionMatrix), std::move(resultLabeling), std::move(transitionResult.markovianStates), std::move(transitionResult.exitRates), std::move(stateRewards), boost::optional<storm::storage::SparseMatrix<double>>(), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 
 			return resultingAutomaton;
 		}
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 10682dc04..0fac2eb18 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -170,6 +170,10 @@ namespace storm {
 			uint_fast64_t lastsource = 0;
 			bool encounteredEOF = false;
 			uint_fast64_t currentChoice = 0;
+
+			// The first choice of the first state already starts a new row group of the matrix.
+			result.transitionMatrixBuilder.newRowGroup(0);
+
 			while (buf[0] != '\0' && !encounteredEOF) {
 				// At the current point, the next thing to read is the source state of the next choice to come.
 				source = checked_strtol(buf, &buf);
@@ -178,7 +182,7 @@ namespace storm {
 				if (source > lastsource + 1) {
 					if (fixDeadlocks) {
 						for (uint_fast64_t index = lastsource + 1; index < source; ++index) {
-							result.nondeterministicChoiceIndices[index] = currentChoice;
+							result.transitionMatrixBuilder.newRowGroup(currentChoice);
 							result.transitionMatrixBuilder.addNextValue(currentChoice, index, 1);
 							++currentChoice;
 						}
@@ -190,7 +194,7 @@ namespace storm {
 
 				if (source != lastsource) {
 					// If we skipped to a new state we need to record the beginning of the choices in the nondeterministic choice indices.
-					result.nondeterministicChoiceIndices[source] = currentChoice;
+					result.transitionMatrixBuilder.newRowGroup(currentChoice);
 				}
 
 				// Record that the current source was the last source.
@@ -253,7 +257,7 @@ namespace storm {
 			}
 
 			// Put a sentinel element at the end.
-			result.nondeterministicChoiceIndices[firstPassResult.highestStateIndex + 1] = currentChoice;
+			result.transitionMatrixBuilder.newRowGroup(currentChoice);
 
 			return result;
 		}
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index c6019d934..de82c28b8 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -52,16 +52,13 @@ namespace storm {
 				 *
 				 * @param firstPassResult A reference to the result of the first pass.
 				 */
-				Result(FirstPassResult const& firstPassResult) : transitionMatrixBuilder(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1, firstPassResult.numberOfNonzeroEntries), nondeterministicChoiceIndices(firstPassResult.highestStateIndex + 2), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
+				Result(FirstPassResult const& firstPassResult) : transitionMatrixBuilder(firstPassResult.numberOfChoices, firstPassResult.highestStateIndex + 1, firstPassResult.numberOfNonzeroEntries, true, firstPassResult.highestStateIndex + 1), markovianChoices(firstPassResult.numberOfChoices), markovianStates(firstPassResult.highestStateIndex + 1), exitRates(firstPassResult.highestStateIndex + 1) {
 					// Intentionally left empty.
 				}
 
 				//! A matrix representing the transitions of the model.
 				storm::storage::SparseMatrixBuilder<double> transitionMatrixBuilder;
 
-				//! A vector indicating which rows of the matrix represent the choices of a given state.
-				std::vector<uint_fast64_t> nondeterministicChoiceIndices;
-
 				//! A bit vector indicating which choices are Markovian. By duality, all other choices are probabilitic.
 				storm::storage::BitVector markovianChoices;
 
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index d150b8c84..fc66dacfb 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -20,9 +20,9 @@ namespace storm {
 		NondeterministicModelParser::Result NondeterministicModelParser::parseNondeterministicModel(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
 			// Parse the transitions.
-			NondeterministicSparseTransitionParser::Result transitions(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionsFilename)));
+			storm::storage::SparseMatrix<double> transitions(std::move(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(transitionsFilename)));
 
-			uint_fast64_t stateCount = transitions.transitionMatrix.getColumnCount();
+			uint_fast64_t stateCount = transitions.getColumnCount();
 
 			// Parse the state labeling.
 			storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFilename)));
@@ -36,11 +36,11 @@ namespace storm {
 			// Only parse transition rewards if a file is given.
 			boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
 			if (transitionRewardFilename != "") {
-				transitionRewards = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFilename, transitions).transitionMatrix;
+				transitionRewards = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(transitionRewardFilename, transitions);
 			}
 
 			// Construct the result.
-			Result result(std::move(transitions.transitionMatrix), std::move(transitions.rowMapping), std::move(labeling));
+			Result result(std::move(transitions), std::move(labeling));
 			result.stateRewards = stateRewards;
 			result.transitionRewards = transitionRewards;
 
@@ -50,13 +50,13 @@ namespace storm {
 		storm::models::Mdp<double> NondeterministicModelParser::parseMdp(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
 			Result parserResult = parseNondeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename);
-			return storm::models::Mdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+			return storm::models::Mdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 		}
 
 		storm::models::Ctmdp<double> NondeterministicModelParser::parseCtmdp(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
 
 			Result parserResult = parseNondeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename);
-			return storm::models::Ctmdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.rowMapping), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
+			return storm::models::Ctmdp<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
 		}
 
 	} /* namespace parser */
diff --git a/src/parser/NondeterministicModelParser.h b/src/parser/NondeterministicModelParser.h
index 376c3e8c6..5de438fde 100644
--- a/src/parser/NondeterministicModelParser.h
+++ b/src/parser/NondeterministicModelParser.h
@@ -33,10 +33,9 @@ namespace storm {
 				 * The copy constructor.
 				 *
 				 * @param transitionSystem The transition system to be contained in the Result.
-				 * @param rowMapping The mapping between matrix rows and model states to be contained in the Result.
 				 * @param labeling The the labeling of the transition system to be contained in the Result.
 				 */
-				Result(storm::storage::SparseMatrix<double>& transitionSystem, std::vector<uint_fast64_t>& rowMapping, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling), rowMapping(rowMapping) {
+				Result(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
 					// Intentionally left empty.
 				}
 
@@ -44,10 +43,9 @@ namespace storm {
 				 * The move constructor.
 				 *
 				 * @param transitionSystem The transition system to be contained in the Result.
-				 * @param rowMapping The mapping between matrix rows and model states to be contained in the Result.
 				 * @param labeling The the labeling of the transition system to be contained in the Result.
 				 */
-				Result(storm::storage::SparseMatrix<double>&& transitionSystem, std::vector<uint_fast64_t>&& rowMapping, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)), rowMapping(std::move(rowMapping)) {
+				Result(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
 					// Intentionally left empty.
 				}
 
@@ -61,12 +59,6 @@ namespace storm {
 				 */
 				storm::models::AtomicPropositionsLabeling labeling;
 
-				/*!
-				 * A mapping from rows of the matrix to states of the model.
-                 * This resolves the nondeterministic choices inside the transition system.
-				 */
-				std::vector<uint_fast64_t> rowMapping;
-
 				/*!
 				 * Optional rewards for each state.
 				 */
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 6e16b2f43..3d8a0826c 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -26,19 +26,19 @@ namespace storm {
 
 		using namespace storm::utility::cstring;
 
-		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitions(std::string const& filename) {
+		storm::storage::SparseMatrix<double> NondeterministicSparseTransitionParser::parseNondeterministicTransitions(std::string const& filename) {
 
-			Result emptyResult;
+			storm::storage::SparseMatrix<double> emptyMatrix;
 
-			return NondeterministicSparseTransitionParser::parse(filename, false, emptyResult);
+			return NondeterministicSparseTransitionParser::parse(filename, false, emptyMatrix);
 		}
 
-		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(std::string const& filename, Result const & modelInformation) {
+		storm::storage::SparseMatrix<double> NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & modelInformation) {
 
 			return NondeterministicSparseTransitionParser::parse(filename, true, modelInformation);
 		}
 
-		NondeterministicSparseTransitionParser::Result NondeterministicSparseTransitionParser::parse(std::string const &filename, bool isRewardFile, Result const & modelInformation) {
+		storm::storage::SparseMatrix<double> NondeterministicSparseTransitionParser::parse(std::string const &filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & modelInformation) {
 
 			// Enforce locale where decimal point is '.'.
 			setlocale(LC_NUMERIC, "C");
@@ -72,17 +72,17 @@ namespace storm {
 
 			if (isRewardFile) {
 				// The reward matrix should match the size of the transition matrix.
-				if (firstPass.choices > modelInformation.transitionMatrix.getRowCount() || (uint_fast64_t)(firstPass.highestStateIndex + 1) > modelInformation.transitionMatrix.getColumnCount()) {
+				if (firstPass.choices > modelInformation.getRowCount() || (uint_fast64_t)(firstPass.highestStateIndex + 1) > modelInformation.getColumnCount()) {
 					LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size.");
 					throw storm::exceptions::OutOfRangeException() << "Reward matrix size exceeds transition matrix size.";
-				} else if (firstPass.choices != modelInformation.transitionMatrix.getRowCount()) {
+				} else if (firstPass.choices != modelInformation.getRowCount()) {
 					LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count.");
 					throw storm::exceptions::OutOfRangeException() << "Reward matrix row count does not match transition matrix row count.";
-				} else if(firstPass.numberOfNonzeroEntries > modelInformation.transitionMatrix.getEntryCount()) {
+				} else if(firstPass.numberOfNonzeroEntries > modelInformation.getEntryCount()) {
 					LOG4CPLUS_ERROR(logger, "The reward matrix has more entries than the transition matrix. There must be a reward for a non existent transition");
 					throw storm::exceptions::OutOfRangeException() << "The reward matrix has more entries than the transition matrix.";
 				} else {
-					firstPass.highestStateIndex = modelInformation.transitionMatrix.getColumnCount() - 1;
+					firstPass.highestStateIndex = modelInformation.getColumnCount() - 1;
 				}
 			}
 
@@ -90,10 +90,12 @@ namespace storm {
 			// The matrix to be build should have as many columns as we have nodes and as many rows as we have choices.
 			// Those two values, as well as the number of nonzero elements, was been calculated in the first run.
 			LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << firstPass.choices << " x " << (firstPass.highestStateIndex+1) << " with " << firstPass.numberOfNonzeroEntries << " entries.");
-			storm::storage::SparseMatrixBuilder<double> matrixBuilder(firstPass.choices, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
-
-			// Create row mapping.
-			std::vector<uint_fast64_t> rowMapping(firstPass.highestStateIndex + 2, 0);
+			storm::storage::SparseMatrixBuilder<double> matrixBuilder;
+			if(!isRewardFile) {
+				matrixBuilder = storm::storage::SparseMatrixBuilder<double>(firstPass.choices, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries, true, firstPass.highestStateIndex + 1);
+			} else {
+				matrixBuilder = storm::storage::SparseMatrixBuilder<double>(firstPass.choices, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries, true, modelInformation.getRowGroupCount());
+			}
 
 			// Initialize variables for the parsing run.
 			uint_fast64_t source = 0, target = 0, lastSource = 0, choice = 0, lastChoice = 0, curRow = 0;
@@ -101,6 +103,9 @@ namespace storm {
 			bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
 			bool hadDeadlocks = false;
 
+			// The first state already starts a new row group of the matrix.
+			matrixBuilder.newRowGroup(0);
+
 			// Read all transitions from file.
 			while (buf[0] != '\0') {
 
@@ -112,13 +117,13 @@ namespace storm {
 					// If we have switched the source state, we possibly need to insert the rows of the last
 					// source state.
 					if (source != lastSource) {
-						curRow += ((modelInformation.rowMapping)[lastSource + 1] - (modelInformation.rowMapping)[lastSource]) -(lastChoice + 1);
+						curRow += ((modelInformation.getRowGroupIndices())[lastSource + 1] - (modelInformation.getRowGroupIndices())[lastSource]) -(lastChoice + 1);
 					}
 
 					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 					// choices.
 					for (uint_fast64_t i = lastSource + 1; i < source; ++i) {
-						curRow += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
+						curRow += ((modelInformation.getRowGroupIndices())[i + 1] - (modelInformation.getRowGroupIndices())[i]);
 					}
 
 					// If we advanced to the next state, but skipped some choices, we have to reserve rows
@@ -140,7 +145,7 @@ namespace storm {
 					for (uint_fast64_t node = lastSource + 1; node < source; node++) {
 						hadDeadlocks = true;
 						if (fixDeadlocks) {
-							rowMapping.at(node) = curRow;
+							matrixBuilder.newRowGroup(curRow);
 							matrixBuilder.addNextValue(curRow, node, 1);
 							++curRow;
 							LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted.");
@@ -150,7 +155,7 @@ namespace storm {
 					}
 					if (source != lastSource) {
 						// Add this source to rowMapping, if this is the first choice we encounter for this state.
-						rowMapping.at(source) = curRow;
+						matrixBuilder.newRowGroup(curRow);
 					}
 				}
 
@@ -168,25 +173,33 @@ namespace storm {
 				buf = trimWhitespaces(buf);
 			}
 
-			for (uint_fast64_t node = lastSource + 1; node <= firstPass.highestStateIndex + 1; node++) {
-				rowMapping.at(node) = curRow + 1;
-			}
-
 			if (!fixDeadlocks && hadDeadlocks && !isRewardFile) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
 
-			// Finally, build the actual matrix, test and return it together with the rowMapping.
+			// Since we assume the transition rewards are for the transitions of the model, we copy the rowGroupIndices.
+			if(isRewardFile) {
+				// We already have rowGroup 0.
+				for(uint_fast64_t index = 1; index < modelInformation.getRowGroupIndices().size(); index++) {
+					matrixBuilder.newRowGroup(modelInformation.getRowGroupIndices()[index]);
+				}
+			} else {
+				for (uint_fast64_t node = lastSource + 1; node <= firstPass.highestStateIndex; node++) {
+					matrixBuilder.newRowGroup(curRow + 1);
+				}
+			}
+
+			// Finally, build the actual matrix, test and return.
 			storm::storage::SparseMatrix<double> resultMatrix = matrixBuilder.build();
 
 			// Since we cannot do the testing if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
-			if(isRewardFile && !resultMatrix.isSubmatrixOf(modelInformation.transitionMatrix)) {
+			if(isRewardFile && !resultMatrix.isSubmatrixOf(modelInformation)) {
 				LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file.");
 				throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file.";
 			}
 
-			return NondeterministicSparseTransitionParser::Result(resultMatrix, rowMapping);
+			return resultMatrix;
 		}
 
-		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, bool isRewardFile, Result const & modelInformation) {
+		NondeterministicSparseTransitionParser::FirstPassResult NondeterministicSparseTransitionParser::firstPass(char* buf, bool isRewardFile, storm::storage::SparseMatrix<double> const & modelInformation) {
 
 			// Check file header and extract number of transitions.
 
@@ -228,13 +241,13 @@ namespace storm {
 					// source state.
 					if (source != lastSource) {
 						// number of choices skipped = number of choices of last state - number of choices read
-						result.choices += ((modelInformation.rowMapping)[lastSource + 1] - (modelInformation.rowMapping)[lastSource]) - (lastChoice + 1);
+						result.choices += ((modelInformation.getRowGroupIndices())[lastSource + 1] - (modelInformation.getRowGroupIndices())[lastSource]) - (lastChoice + 1);
 					}
 
 					// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 					// choices.
 					for (uint_fast64_t i = lastSource + 1; i < source; ++i) {
-						result.choices += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
+						result.choices += ((modelInformation.getRowGroupIndices())[i + 1] - (modelInformation.getRowGroupIndices())[i]);
 					}
 
 					// If we advanced to the next state, but skipped some choices, we have to reserve rows
@@ -302,12 +315,12 @@ namespace storm {
 
 			if (isRewardFile) {
 				// If not all rows were filled for the last state, we need to insert them.
-				result.choices += ((modelInformation.rowMapping)[lastSource + 1] - (modelInformation.rowMapping)[lastSource] ) - (lastChoice + 1);
+				result.choices += ((modelInformation.getRowGroupIndices())[lastSource + 1] - (modelInformation.getRowGroupIndices())[lastSource] ) - (lastChoice + 1);
 
 				// If we skipped some states, we need to reserve empty rows for all their nondeterministic
 				// choices.
-				for (uint_fast64_t i = lastSource + 1; i < modelInformation.rowMapping.size() - 1; ++i) {
-					result.choices += ((modelInformation.rowMapping)[i + 1] - (modelInformation.rowMapping)[i]);
+				for (uint_fast64_t i = lastSource + 1; i < modelInformation.getRowGroupIndices().size() - 1; ++i) {
+					result.choices += ((modelInformation.getRowGroupIndices())[i + 1] - (modelInformation.getRowGroupIndices())[i]);
 				}
 			}
 
diff --git a/src/parser/NondeterministicSparseTransitionParser.h b/src/parser/NondeterministicSparseTransitionParser.h
index aea0f8fcc..f75babbb7 100644
--- a/src/parser/NondeterministicSparseTransitionParser.h
+++ b/src/parser/NondeterministicSparseTransitionParser.h
@@ -43,48 +43,12 @@ namespace storm {
 				uint_fast64_t choices;
 			};
 
-			/*!
-			 * A structure representing the result of the parser.
-			 * It contains the resulting matrix as well as the row mapping.
-			 */
-			struct Result {
-
-				/*!
-				 *  The default constructor.
-				 *  Constructs an empty Result.
-				 */
-				Result() : transitionMatrix(), rowMapping() {
-					// Intentionally left empty.
-				}
-
-				/*!
-				 * Constructs a Result, initializing its members with the given values.
-				 *
-				 * @param transitionMatrix The matrix containing the parsed transition system.
-				 * @param rowMapping A mapping from rows of the matrix to states of the model.
-				 */
-				Result(storm::storage::SparseMatrix<double> transitionMatrix, std::vector<uint_fast64_t> rowMapping) : transitionMatrix(transitionMatrix), rowMapping(rowMapping) {
-					// Intentionally left empty.
-				}
-
-				/*!
-				 * The matrix containing the parsed transition system.
-				 */
-				storm::storage::SparseMatrix<double> transitionMatrix;
-
-				/*!
-				 * A mapping from rows of the matrix to states of the model.
-				 * This resolves the nondeterministic choices inside the transition system.
-				 */
-				std::vector<uint_fast64_t> rowMapping;
-			};
-
 			/*!
 			 * Load a nondeterministic transition system from file and create a sparse adjacency matrix whose entries represent the weights of the edges
 			 *
 			 * @param filename The path and name of file to be parsed.
 			 */
-			static Result parseNondeterministicTransitions(std::string const & filename);
+			static storm::storage::SparseMatrix<double> parseNondeterministicTransitions(std::string const & filename);
 
 			/*!
 			 * Load a nondeterministic transition system from file and create a sparse adjacency matrix whose entries represent the weights of the edges
@@ -93,7 +57,7 @@ namespace storm {
 			 * @param modelInformation The information about the transition structure of nondeterministic model in which the transition rewards shall be used.
 			 * @return A struct containing the parsed file contents, i.e. the transition reward matrix and the mapping between its rows and the states of the model.
 			 */
-			static Result parseNondeterministicTransitionRewards(std::string const & filename, Result const & modelInformation);
+			static storm::storage::SparseMatrix<double> parseNondeterministicTransitionRewards(std::string const & filename, storm::storage::SparseMatrix<double> const & modelInformation);
 
 		private:
 
@@ -110,7 +74,7 @@ namespace storm {
 			 * @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
 			 * @return A structure representing the result of the first pass.
 			 */
-			static FirstPassResult firstPass(char* buffer, bool isRewardFile, Result const & modelInformation);
+			static FirstPassResult firstPass(char* buffer, bool isRewardFile, storm::storage::SparseMatrix<double> const & modelInformation);
 
 			/*!
 			 * The main parsing routine.
@@ -122,7 +86,7 @@ namespace storm {
 			 * @param modelInformation A struct containing information that is used to check if the transition reward matrix fits to the rest of the model.
 			 * @return A SparseMatrix containing the parsed file contents.
 			 */
-			static Result parse(std::string const& filename, bool isRewardFile, Result const & modelInformation);
+			static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & modelInformation);
 
 		};
 	
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index a71d741ad..679bb5e7e 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -36,7 +36,7 @@ namespace storm {
 
 			// Now parse state reward assignments.
 			uint_fast64_t state = 0;
-			uint_fast64_t lastState = -1;
+			uint_fast64_t lastState = (uint_fast64_t)-1;
 			double reward;
 
 			// Iterate over states.
@@ -47,7 +47,7 @@ namespace storm {
 
 				// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
 				// Note: The value -1 shows that lastState has not yet been set, i.e. this is the first run of the loop (state index (2^64)-1 is a really bad starting index).
-				if(state <= lastState && lastState != -1) {
+				if(state <= lastState && lastState != (uint_fast64_t)-1) {
 					LOG4CPLUS_ERROR(logger, "State " << state << " was found but has already been read or skipped previously.");
 					throw storm::exceptions::WrongFormatException() << "State " << state << " was found but has already been read or skipped previously.";
 				}
diff --git a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
index f5dcbc1d2..0af549586 100644
--- a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
@@ -42,22 +42,23 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 	ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
 	ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
 	ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
+	ASSERT_EQ(transitionMatrix.getRowGroupCount(), 6);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices().size(), 7);
 	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
 	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
 	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
 	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
-	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
 
 	// Test the general structure of the transition system (that will be an Markov automaton).
 
 	// Test the mapping between states and transition matrix rows.
-	ASSERT_EQ(result.nondeterministicChoiceIndices[0], 0);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[1], 1);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[2], 2);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[3], 3);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[4], 4);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[5], 6);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[6], 7);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[0], 0);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[1], 1);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[2], 2);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[3], 3);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[4], 4);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[5], 6);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[6], 7);
 
 	// Test the Markovian states.
 	ASSERT_TRUE(result.markovianStates.get(0));
@@ -119,22 +120,23 @@ TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
 	ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
 	ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
 	ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
+	ASSERT_EQ(transitionMatrix.getRowGroupCount(), 6);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices().size(), 7);
 	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
 	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
 	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
 	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
-	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
 
 	// Test the general structure of the transition system (that will be an Markov automaton).
 
 	// Test the mapping between states and transition matrix rows.
-	ASSERT_EQ(result.nondeterministicChoiceIndices[0], 0);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[1], 1);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[2], 2);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[3], 3);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[4], 4);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[5], 6);
-	ASSERT_EQ(result.nondeterministicChoiceIndices[6], 7);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[0], 0);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[1], 1);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[2], 2);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[3], 3);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[4], 4);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[5], 6);
+	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[6], 7);
 
 	// Test the Markovian states.
 	ASSERT_TRUE(result.markovianStates.get(0));
@@ -193,11 +195,12 @@ TEST(MarkovAutomatonSparseTransitionParserTest, FixDeadlocks) {
 	storm::storage::SparseMatrix<double> resultMatrix(result.transitionMatrixBuilder.build(0,0));
 	ASSERT_EQ(resultMatrix.getColumnCount(), STATE_COUNT + 1);
 	ASSERT_EQ(resultMatrix.getEntryCount(), 13);
+	ASSERT_EQ(resultMatrix.getRowGroupCount(), 7);
+	ASSERT_EQ(resultMatrix.getRowGroupIndices().size(), 8);
 	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT +1);
 	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT +1);
 	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
 	ASSERT_EQ(result.exitRates.size(), STATE_COUNT + 1);
-	ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 8);
 }
 
 TEST(MarkovAutomatonSparseTransitionParserTest, DontFixDeadlocks) {
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
index 8fc55cf1c..554d689ea 100644
--- a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -19,7 +19,7 @@ TEST(NondeterministicSparseTransitionParserTest, NonExistingFile) {
 	// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
 
-	storm::parser::NondeterministicSparseTransitionParser::Result nullInformation;
+	storm::storage::SparseMatrix<double> nullInformation;
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", nullInformation), storm::exceptions::FileIoException);
 }
 
@@ -27,25 +27,26 @@ TEST(NondeterministicSparseTransitionParserTest, NonExistingFile) {
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
 	// Parse a nondeterministic transitions file and test the result.
-	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
+	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
 
 	// Test the row mapping, i.e. at which row which state starts.
-	ASSERT_EQ(result.rowMapping.size(), 7);
-	ASSERT_EQ(result.rowMapping[0], 0);
-	ASSERT_EQ(result.rowMapping[1], 4);
-	ASSERT_EQ(result.rowMapping[2], 5);
-	ASSERT_EQ(result.rowMapping[3], 7);
-	ASSERT_EQ(result.rowMapping[4], 8);
-	ASSERT_EQ(result.rowMapping[5], 9);
-	ASSERT_EQ(result.rowMapping[6], 11);
+	ASSERT_EQ(6, result.getRowGroupCount());
+	ASSERT_EQ(7, result.getRowGroupIndices().size());
+	ASSERT_EQ(result.getRowGroupIndices()[0], 0);
+	ASSERT_EQ(result.getRowGroupIndices()[1], 4);
+	ASSERT_EQ(result.getRowGroupIndices()[2], 5);
+	ASSERT_EQ(result.getRowGroupIndices()[3], 7);
+	ASSERT_EQ(result.getRowGroupIndices()[4], 8);
+	ASSERT_EQ(result.getRowGroupIndices()[5], 9);
+	ASSERT_EQ(result.getRowGroupIndices()[6], 11);
 
 	// Test the transition matrix.
-	ASSERT_EQ(result.transitionMatrix.getColumnCount(), 6);
-	ASSERT_EQ(result.transitionMatrix.getRowCount(), 11);
-	ASSERT_EQ(result.transitionMatrix.getEntryCount(), 22);
+	ASSERT_EQ(result.getColumnCount(), 6);
+	ASSERT_EQ(result.getRowCount(), 11);
+	ASSERT_EQ(result.getEntryCount(), 22);
 
 	// Test every entry of the matrix.
-	storm::storage::SparseMatrix<double>::const_iterator cIter = result.transitionMatrix.begin(0);
+	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
 
 	ASSERT_EQ(cIter->first, 0);
 	ASSERT_EQ(cIter->second, 0.9);
@@ -116,8 +117,8 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
 	// Parse a nondeterministic transitions file and test the result.
-	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
-	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", modelInformation).transitionMatrix);
+	storm::storage::SparseMatrix<double> modelInformation(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
+	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", modelInformation));
 
 	// Test the transition matrix.
 	ASSERT_EQ(result.getColumnCount(), 6);
@@ -182,17 +183,17 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing)
 TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
 	// Test the resilience of the parser against whitespaces.
 	// Do so by comparing the hashes of the transition matices and the rowMapping vectors element by element.
-	storm::parser::NondeterministicSparseTransitionParser::Result correctResult(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
-	storm::parser::NondeterministicSparseTransitionParser::Result whitespaceResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_whitespaces.tra");
-	ASSERT_EQ(correctResult.transitionMatrix.hash(), whitespaceResult.transitionMatrix.hash());
-	ASSERT_EQ(correctResult.rowMapping.size(), whitespaceResult.rowMapping.size());
-	for(uint_fast64_t i = 0; i < correctResult.rowMapping.size(); i++) {
-		ASSERT_EQ(correctResult.rowMapping[i], whitespaceResult.rowMapping[i]);
+	storm::storage::SparseMatrix<double> correctResult(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
+	storm::storage::SparseMatrix<double> whitespaceResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_whitespaces.tra");
+	ASSERT_EQ(correctResult.hash(), whitespaceResult.hash());
+	ASSERT_EQ(correctResult.getRowGroupIndices().size(), whitespaceResult.getRowGroupIndices().size());
+	for(uint_fast64_t i = 0; i < correctResult.getRowGroupIndices().size(); i++) {
+		ASSERT_EQ(correctResult.getRowGroupIndices()[i], whitespaceResult.getRowGroupIndices()[i]);
 	}
 
 	// Do the same (minus the unused rowMapping) for the corresponding transition rewards file (with and without whitespaces)
-	uint_fast64_t correctHash = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", correctResult).transitionMatrix.hash();
-	ASSERT_EQ(correctHash, storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_whitespaces.trans.rew", whitespaceResult).transitionMatrix.hash());
+	uint_fast64_t correctHash = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", correctResult).hash();
+	ASSERT_EQ(correctHash, storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_whitespaces.trans.rew", whitespaceResult).hash());
 }
 
 TEST(NondeterministicSparseTransitionParserTest, MixedTransitionOrder) {
@@ -200,7 +201,7 @@ TEST(NondeterministicSparseTransitionParserTest, MixedTransitionOrder) {
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedTransitionOrder.tra"), storm::exceptions::InvalidArgumentException);
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedStateOrder.tra"), storm::exceptions::InvalidArgumentException);
 
-	storm::parser::NondeterministicSparseTransitionParser::Result modelInformation = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
+	storm::storage::SparseMatrix<double> modelInformation = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedTransitionOrder.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedStateOrder.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
 }
@@ -210,18 +211,18 @@ TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
 	storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
 
 	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
-	storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"));
+	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"));
 
-	ASSERT_EQ(result.rowMapping.size(), 8);
-	ASSERT_EQ(result.rowMapping[5], 9);
-	ASSERT_EQ(result.rowMapping[6], 10);
-	ASSERT_EQ(result.rowMapping[7], 12);
+	ASSERT_EQ(result.getRowGroupIndices().size(), 8);
+	ASSERT_EQ(result.getRowGroupIndices()[5], 9);
+	ASSERT_EQ(result.getRowGroupIndices()[6], 10);
+	ASSERT_EQ(result.getRowGroupIndices()[7], 12);
 
-	ASSERT_EQ(result.transitionMatrix.getColumnCount(), 7);
-	ASSERT_EQ(result.transitionMatrix.getRowCount(), 12);
-	ASSERT_EQ(result.transitionMatrix.getEntryCount(), 23);
+	ASSERT_EQ(result.getColumnCount(), 7);
+	ASSERT_EQ(result.getRowCount(), 12);
+	ASSERT_EQ(result.getEntryCount(), 23);
 
-	storm::storage::SparseMatrix<double>::const_iterator cIter = result.transitionMatrix.begin(8);
+	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(8);
 
 	ASSERT_EQ(cIter->first, 1);
 	ASSERT_EQ(cIter->second, 0.7);
@@ -261,7 +262,7 @@ TEST(NondeterministicSparseTransitionParserTest, DoubledLines) {
 TEST(NondeterministicSparseTransitionParserTest, RewardForNonExistentTransition) {
 
 	// First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
-	storm::parser::NondeterministicSparseTransitionParser::Result transitionResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
+	storm::storage::SparseMatrix<double> transitionResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
 
 	// There is a reward for a transition that does not exist in the transition matrix.
 	ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_rewardForNonExTrans.trans.rew", transitionResult), storm::exceptions::WrongFormatException);

From 8f171c7dc5fa6a793b1cd8df37581521e566793c Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Thu, 13 Mar 2014 00:15:41 +0100
Subject: [PATCH 023/147] Finished initial remerge.

- Fixed comments.
- It seems to be ASSERT_EQ(expected, actual);
|-> Switched arguments of nearly all ASSERT_EQs to correctly use this macro in the parser tests.


Former-commit-id: e5059709f2df49e5974e383c8004fa1c1afb5174
---
 .../MarkovAutomatonSparseTransitionParser.cpp |   3 +-
 .../MarkovAutomatonSparseTransitionParser.h   |   2 +-
 ...NondeterministicSparseTransitionParser.cpp |   7 +-
 test/functional/parser/AutoParserTest.cpp     |  38 +--
 .../parser/DeterministicModelParserTest.cpp   |  36 +--
 ...eterministicSparseTransitionParserTest.cpp | 180 +++++++-------
 test/functional/parser/MappedFileTest.cpp     |   4 +-
 .../parser/MarkovAutomatonParserTest.cpp      |  30 +--
 ...kovAutomatonSparseTransitionParserTest.cpp | 156 ++++++------
 .../NondeterministicModelParserTest.cpp       |  42 ++--
 ...eterministicSparseTransitionParserTest.cpp | 224 +++++++++---------
 .../parser/SparseStateRewardParserTest.cpp    |   4 +-
 12 files changed, 364 insertions(+), 362 deletions(-)

diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 0fac2eb18..21403c3be 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -31,6 +31,7 @@ namespace storm {
 			bool stateHasMarkovianChoice = false;
 			bool stateHasProbabilisticChoice = false;
 			while (buf[0] != '\0' && !encounteredEOF) {
+
 				// At the current point, the next thing to read is the source state of the next choice to come.
 				source = checked_strtol(buf, &buf);
 
@@ -193,7 +194,7 @@ namespace storm {
 				}
 
 				if (source != lastsource) {
-					// If we skipped to a new state we need to record the beginning of the choices in the nondeterministic choice indices.
+					// If we skipped to a new state we need to create a new row group for the choices of the new state.
 					result.transitionMatrixBuilder.newRowGroup(currentChoice);
 				}
 
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.h b/src/parser/MarkovAutomatonSparseTransitionParser.h
index de82c28b8..798a9e0e3 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.h
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.h
@@ -12,7 +12,7 @@ namespace storm {
 		 *
 		 * The file is parsed in two passes.
 		 * The first pass tests the file format and collects statistical data needed for the second pass.
-		 * The second pass then collects the actual file data and compiles it into a ResultType.
+		 * The second pass then collects the actual file data and compiles it into a Result.
 		 */
 		class MarkovAutomatonSparseTransitionParser {
 		public:
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 3d8a0826c..7d6fbb527 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -139,9 +139,10 @@ namespace storm {
 					if ((source != lastSource || choice != lastChoice)) {
 						++curRow;
 					}
+
 					// Check if we have skipped any source node, i.e. if any node has no
 					// outgoing transitions. If so, insert a self-loop.
-					// Also add self-loops to rowMapping.
+					// Also begin a new rowGroup for the skipped state.
 					for (uint_fast64_t node = lastSource + 1; node < source; node++) {
 						hadDeadlocks = true;
 						if (fixDeadlocks) {
@@ -154,7 +155,7 @@ namespace storm {
 						}
 					}
 					if (source != lastSource) {
-						// Add this source to rowMapping, if this is the first choice we encounter for this state.
+						// Add create a new rowGroup for the source, if this is the first choice we encounter for this state.
 						matrixBuilder.newRowGroup(curRow);
 					}
 				}
@@ -187,7 +188,7 @@ namespace storm {
 				}
 			}
 
-			// Finally, build the actual matrix, test and return.
+			// Finally, build the actual matrix, test and return it.
 			storm::storage::SparseMatrix<double> resultMatrix = matrixBuilder.build();
 
 			// Since we cannot do the testing if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
diff --git a/test/functional/parser/AutoParserTest.cpp b/test/functional/parser/AutoParserTest.cpp
index a9a15a228..3c4927ecd 100644
--- a/test/functional/parser/AutoParserTest.cpp
+++ b/test/functional/parser/AutoParserTest.cpp
@@ -22,10 +22,10 @@ TEST(AutoParserTest, BasicParsing) {
 	std::shared_ptr<storm::models::AbstractModel<double>> modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 
 	// Test if parsed correctly.
-	ASSERT_EQ(modelPtr->getType(), storm::models::DTMC);
-	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
-	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 32);
-	ASSERT_EQ(modelPtr->getInitialStates().getNumberOfSetBits(), 1);
+	ASSERT_EQ(storm::models::DTMC, modelPtr->getType());
+	ASSERT_EQ(12, modelPtr->getNumberOfStates());
+	ASSERT_EQ(32, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(1, modelPtr->getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(modelPtr->hasAtomicProposition("three"));
 	ASSERT_FALSE(modelPtr->hasStateRewards());
 	ASSERT_FALSE(modelPtr->hasTransitionRewards());
@@ -54,23 +54,23 @@ TEST(AutoParserTest, Decision) {
 
 	// Dtmc
 	std::shared_ptr<storm::models::AbstractModel<double>> modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
-	ASSERT_EQ(modelPtr->getType(), storm::models::DTMC);
-	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
-	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 32);
+	ASSERT_EQ(storm::models::DTMC, modelPtr->getType());
+	ASSERT_EQ(12, modelPtr->getNumberOfStates());
+	ASSERT_EQ(32, modelPtr->getNumberOfTransitions());
 
 	// Ctmc
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ctmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
-	ASSERT_EQ(modelPtr->getType(), storm::models::CTMC);
-	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
-	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 31);
+	ASSERT_EQ(storm::models::CTMC, modelPtr->getType());
+	ASSERT_EQ(12, modelPtr->getNumberOfStates());
+	ASSERT_EQ(31, modelPtr->getNumberOfTransitions());
 
 	// Mdp
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/mdp.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
-	ASSERT_EQ(modelPtr->getType(), storm::models::MDP);
-	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
-	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 36);
+	ASSERT_EQ(storm::models::MDP, modelPtr->getType());
+	ASSERT_EQ(12, modelPtr->getNumberOfStates());
+	ASSERT_EQ(36, modelPtr->getNumberOfTransitions());
 
 	// Ctmdp
 	// Note: For now we use the Mdp from above just given the ctmdp hint, since the implementation of the Ctmdp model seems not Quite right yet.
@@ -78,14 +78,14 @@ TEST(AutoParserTest, Decision) {
 	// TODO: Fix the Ctmdp implementation and use an actual Ctmdp for testing.
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ctmdp.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
-	ASSERT_EQ(modelPtr->getType(), storm::models::CTMDP);
-	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
-	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 36);
+	ASSERT_EQ(storm::models::CTMDP, modelPtr->getType());
+	ASSERT_EQ(12, modelPtr->getNumberOfStates());
+	ASSERT_EQ(36, modelPtr->getNumberOfTransitions());
 
 	// MA
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ma.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
-	ASSERT_EQ(modelPtr->getType(), storm::models::MA);
-	ASSERT_EQ(modelPtr->getNumberOfStates(), 12);
-	ASSERT_EQ(modelPtr->getNumberOfTransitions(), 35);
+	ASSERT_EQ(storm::models::MA, modelPtr->getType());
+	ASSERT_EQ(12, modelPtr->getNumberOfStates());
+	ASSERT_EQ(35, modelPtr->getNumberOfTransitions());
 }
diff --git a/test/functional/parser/DeterministicModelParserTest.cpp b/test/functional/parser/DeterministicModelParserTest.cpp
index 69f1ff086..4a62e5e6e 100644
--- a/test/functional/parser/DeterministicModelParserTest.cpp
+++ b/test/functional/parser/DeterministicModelParserTest.cpp
@@ -25,30 +25,30 @@ TEST(DeterministicModelParserTest, BasicDtmcParsing) {
 	// Parse a Dtmc and check the result.
 	storm::models::Dtmc<double> dtmc(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"));
 
-	ASSERT_EQ(dtmc.getNumberOfStates(), 8);
-	ASSERT_EQ(dtmc.getNumberOfTransitions(), 21);
+	ASSERT_EQ(8, dtmc.getNumberOfStates());
+	ASSERT_EQ(21, dtmc.getNumberOfTransitions());
 
-	ASSERT_EQ(dtmc.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_EQ(2, dtmc.getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(dtmc.getInitialStates().get(0));
 	ASSERT_TRUE(dtmc.getInitialStates().get(7));
-	ASSERT_EQ(dtmc.getStateLabeling().getNumberOfAtomicPropositions(), 5);
-	ASSERT_EQ(dtmc.getLabelsForState(6).size(), 2);
+	ASSERT_EQ(5, dtmc.getStateLabeling().getNumberOfAtomicPropositions());
+	ASSERT_EQ(2, dtmc.getLabelsForState(6).size());
 
 	ASSERT_TRUE(dtmc.hasStateRewards());
-	ASSERT_EQ(dtmc.getStateRewardVector()[7], 42);
+	ASSERT_EQ(42, dtmc.getStateRewardVector()[7]);
 	double rewardSum = 0;
 	for(uint_fast64_t i = 0; i < dtmc.getStateRewardVector().size(); i++) {
 		rewardSum += dtmc.getStateRewardVector()[i];
 	}
-	ASSERT_EQ(rewardSum, 263.32);
+	ASSERT_EQ(263.32, rewardSum);
 
 	ASSERT_TRUE(dtmc.hasTransitionRewards());
-	ASSERT_EQ(dtmc.getTransitionRewardMatrix().getEntryCount(), 17);
+	ASSERT_EQ(17, dtmc.getTransitionRewardMatrix().getEntryCount());
 	rewardSum = 0;
 	for(uint_fast64_t i = 0; i < dtmc.getTransitionRewardMatrix().getRowCount(); i++) {
 			rewardSum += dtmc.getTransitionRewardMatrix().getRowSum(i);
 	}
-	ASSERT_EQ(rewardSum, 125.4);
+	ASSERT_EQ(125.4, rewardSum);
 }
 
 
@@ -57,30 +57,30 @@ TEST(DeterministicModelParserTest, BasicCtmcParsing) {
 	// Parse a Ctmc and check the result.
 	storm::models::Ctmc<double> ctmc(storm::parser::DeterministicModelParser::parseCtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"));
 
-	ASSERT_EQ(ctmc.getNumberOfStates(), 8);
-	ASSERT_EQ(ctmc.getNumberOfTransitions(), 21);
+	ASSERT_EQ(8, ctmc.getNumberOfStates());
+	ASSERT_EQ(21, ctmc.getNumberOfTransitions());
 
-	ASSERT_EQ(ctmc.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_EQ(2, ctmc.getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(ctmc.getInitialStates().get(0));
 	ASSERT_TRUE(ctmc.getInitialStates().get(7));
-	ASSERT_EQ(ctmc.getStateLabeling().getNumberOfAtomicPropositions(), 5);
-	ASSERT_EQ(ctmc.getLabelsForState(6).size(), 2);
+	ASSERT_EQ(5, ctmc.getStateLabeling().getNumberOfAtomicPropositions());
+	ASSERT_EQ(2, ctmc.getLabelsForState(6).size());
 
 	ASSERT_TRUE(ctmc.hasStateRewards());
-	ASSERT_EQ(ctmc.getStateRewardVector()[7], 42);
+	ASSERT_EQ(42, ctmc.getStateRewardVector()[7]);
 	double rewardSum = 0;
 	for(uint_fast64_t i = 0; i < ctmc.getStateRewardVector().size(); i++) {
 		rewardSum += ctmc.getStateRewardVector()[i];
 	}
-	ASSERT_EQ(rewardSum, 263.32);
+	ASSERT_EQ(263.32, rewardSum);
 
 	ASSERT_TRUE(ctmc.hasTransitionRewards());
-	ASSERT_EQ(ctmc.getTransitionRewardMatrix().getEntryCount(), 17);
+	ASSERT_EQ(17, ctmc.getTransitionRewardMatrix().getEntryCount());
 	rewardSum = 0;
 	for(uint_fast64_t i = 0; i < ctmc.getTransitionRewardMatrix().getRowCount(); i++) {
 			rewardSum += ctmc.getTransitionRewardMatrix().getRowSum(i);
 	}
-	ASSERT_EQ(rewardSum, 125.4);
+	ASSERT_EQ(125.4, rewardSum);
 }
 
 TEST(DeterministicModelParserTest, MismatchedFiles) {
diff --git a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
index 0e78f0992..2b301a1e7 100644
--- a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
@@ -29,74 +29,74 @@ TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 	// Parse a deterministic transitions file and test the resulting matrix.
 	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
 
-	ASSERT_EQ(transitionMatrix.getColumnCount(), 8);
-	ASSERT_EQ(transitionMatrix.getEntryCount(), 21);
+	ASSERT_EQ(8, transitionMatrix.getColumnCount());
+	ASSERT_EQ(21, transitionMatrix.getEntryCount());
 
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
 
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.4);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.4, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.4);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.4, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 0.7);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(0.7, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 0.9);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(0.9, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 0.224653);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(0.224653, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 7);
-	ASSERT_EQ(cIter->second, 0.775347);
+	ASSERT_EQ(7, cIter->first);
+	ASSERT_EQ(0.775347, cIter->second);
 }
 
 TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
@@ -106,62 +106,62 @@ TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
 
 	storm::storage::SparseMatrix<double> rewardMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew", transitionMatrix);
 
-	ASSERT_EQ(rewardMatrix.getColumnCount(), 8);
-	ASSERT_EQ(rewardMatrix.getEntryCount(), 17);
+	ASSERT_EQ(8, rewardMatrix.getColumnCount());
+	ASSERT_EQ(17, rewardMatrix.getEntryCount());
 
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = rewardMatrix.begin(0);
 
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 10);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(10, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 5);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 5.5);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(5.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 21.4);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(21.4, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 4);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(4, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 2);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 1.1);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(1.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 9.5);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(9.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 6.7);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(6.7, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 12);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(12, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 35.224653);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(35.224653, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 7);
-	ASSERT_EQ(cIter->second, 9.875347);
+	ASSERT_EQ(7, cIter->first);
+	ASSERT_EQ(9.875347, cIter->second);
 }
 
 
@@ -197,21 +197,21 @@ TEST(DeterministicSparseTransitionParserTest, FixDeadlocks) {
 	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
 	storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock.tra");
 
-	ASSERT_EQ(transitionMatrix.getColumnCount(), 9);
-	ASSERT_EQ(transitionMatrix.getEntryCount(), 23);
+	ASSERT_EQ(9, transitionMatrix.getColumnCount());
+	ASSERT_EQ(23, transitionMatrix.getEntryCount());
 
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(7);
-	ASSERT_EQ(cIter->first, 7);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(7, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 6);
-	ASSERT_EQ(cIter->second, 0.224653);
+	ASSERT_EQ(6, cIter->first);
+	ASSERT_EQ(0.224653, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 7);
-	ASSERT_EQ(cIter->second, 0.775347);
+	ASSERT_EQ(7, cIter->first);
+	ASSERT_EQ(0.775347, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 8);
-	ASSERT_EQ(cIter->second, 0);
+	ASSERT_EQ(8, cIter->first);
+	ASSERT_EQ(0, cIter->second);
 }
 
 TEST(DeterministicSparseTransitionParserTest, DontFixDeadlocks) {
diff --git a/test/functional/parser/MappedFileTest.cpp b/test/functional/parser/MappedFileTest.cpp
index f63632362..a86ecb7cc 100644
--- a/test/functional/parser/MappedFileTest.cpp
+++ b/test/functional/parser/MappedFileTest.cpp
@@ -22,10 +22,10 @@ TEST(MappedFileTest, BasicFunctionality) {
 	// Open a file and test if the content is loaded as expected.
 	storm::parser::MappedFile file(STORM_CPP_TESTS_BASE_PATH "/functional/parser/testStringFile.txt");
 	std::string testString = "This is a test string.\n";
-	ASSERT_EQ(file.getDataEnd() - file.getData(), testString.length());
+	ASSERT_EQ(testString.length(), file.getDataEnd() - file.getData());
 	char const * testStringPtr = testString.c_str();
 	for(char* dataPtr = file.getData(); dataPtr < file.getDataEnd(); dataPtr++) {
-		ASSERT_EQ(*dataPtr, *testStringPtr);
+		ASSERT_EQ(*testStringPtr, *dataPtr);
 		testStringPtr++;
 	}
 }
diff --git a/test/functional/parser/MarkovAutomatonParserTest.cpp b/test/functional/parser/MarkovAutomatonParserTest.cpp
index 017be55af..4668105b9 100644
--- a/test/functional/parser/MarkovAutomatonParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonParserTest.cpp
@@ -23,28 +23,28 @@ TEST(MarkovAutomatonParserTest, BasicParsing) {
 	storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general.state.rew");
 
 	// Test sizes and counts.
-	ASSERT_EQ(result.getNumberOfStates(), 6);
-	ASSERT_EQ(result.getNumberOfChoices(), 7);
-	ASSERT_EQ(result.getNumberOfTransitions(), 12);
+	ASSERT_EQ(6, result.getNumberOfStates());
+	ASSERT_EQ(7, result.getNumberOfChoices());
+	ASSERT_EQ(12, result.getNumberOfTransitions());
 
 	// Test the exit rates. These have to be 0 for all non-Markovian states.
 	std::vector<double> rates = result.getExitRates();
-	ASSERT_EQ(result.getExitRate(0), 2);
+	ASSERT_EQ(2, result.getExitRate(0));
 	ASSERT_FALSE(result.isMarkovianState(1));
-	ASSERT_EQ(result.getExitRate(1), 0);
-	ASSERT_EQ(result.getExitRate(2), 15);
+	ASSERT_EQ(0, result.getExitRate(1));
+	ASSERT_EQ(15, result.getExitRate(2));
 	ASSERT_FALSE(result.isMarkovianState(3));
-	ASSERT_EQ(result.getExitRate(3), 0);
+	ASSERT_EQ(0, result.getExitRate(3));
 	ASSERT_FALSE(result.isMarkovianState(4));
-	ASSERT_EQ(result.getExitRate(4), 0);
+	ASSERT_EQ(0, result.getExitRate(4));
 	ASSERT_FALSE(result.isMarkovianState(5));
-	ASSERT_EQ(result.getExitRate(5), 0);
+	ASSERT_EQ(0, result.getExitRate(5));
 
 	// Test the labeling.
-	ASSERT_EQ(result.getStateLabeling().getNumberOfAtomicPropositions(), 3);
-	ASSERT_EQ(result.getInitialStates().getNumberOfSetBits(), 1);
-	ASSERT_EQ(result.getLabelsForState(4).size(), 0);
-	ASSERT_EQ(result.getStateLabeling().getLabeledStates("goal").getNumberOfSetBits(), 1);
+	ASSERT_EQ(3, result.getStateLabeling().getNumberOfAtomicPropositions());
+	ASSERT_EQ(1, result.getInitialStates().getNumberOfSetBits());
+	ASSERT_EQ(0, result.getLabelsForState(4).size());
+	ASSERT_EQ(1, result.getStateLabeling().getLabeledStates("goal").getNumberOfSetBits());
 
 	// Test the state rewards.
 	ASSERT_TRUE(result.hasStateRewards());
@@ -52,8 +52,8 @@ TEST(MarkovAutomatonParserTest, BasicParsing) {
 	for(uint_fast64_t i = 0; i < result.getStateRewardVector().size(); i++) {
 		rewardSum += result.getStateRewardVector()[i];
 	}
-	ASSERT_EQ(rewardSum, 1015.765099984);
-	ASSERT_EQ(result.getStateRewardVector()[0], 0);
+	ASSERT_EQ(1015.765099984, rewardSum);
+	ASSERT_EQ(0, result.getStateRewardVector()[0]);
 
 	// Test the transition rewards.
 	ASSERT_FALSE(result.hasTransitionRewards());
diff --git a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
index 0af549586..81c2ccfb8 100644
--- a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
@@ -39,26 +39,26 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
 
 	// Test all sizes and counts.
-	ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
-	ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
-	ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
-	ASSERT_EQ(transitionMatrix.getRowGroupCount(), 6);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices().size(), 7);
-	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
-	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
-	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
-	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
+	ASSERT_EQ(STATE_COUNT, transitionMatrix.getColumnCount());
+	ASSERT_EQ(CHOICE_COUNT, transitionMatrix.getRowCount());
+	ASSERT_EQ(12, transitionMatrix.getEntryCount());
+	ASSERT_EQ(6, transitionMatrix.getRowGroupCount());
+	ASSERT_EQ(7, transitionMatrix.getRowGroupIndices().size());
+	ASSERT_EQ(CHOICE_COUNT, result.markovianChoices.size());
+	ASSERT_EQ(STATE_COUNT, result.markovianStates.size());
+	ASSERT_EQ(2, result.markovianStates.getNumberOfSetBits());
+	ASSERT_EQ(STATE_COUNT, result.exitRates.size());
 
 	// Test the general structure of the transition system (that will be an Markov automaton).
 
 	// Test the mapping between states and transition matrix rows.
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[0], 0);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[1], 1);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[2], 2);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[3], 3);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[4], 4);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[5], 6);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[6], 7);
+	ASSERT_EQ(0, transitionMatrix.getRowGroupIndices()[0]);
+	ASSERT_EQ(1, transitionMatrix.getRowGroupIndices()[1]);
+	ASSERT_EQ(2, transitionMatrix.getRowGroupIndices()[2]);
+	ASSERT_EQ(3, transitionMatrix.getRowGroupIndices()[3]);
+	ASSERT_EQ(4, transitionMatrix.getRowGroupIndices()[4]);
+	ASSERT_EQ(6, transitionMatrix.getRowGroupIndices()[5]);
+	ASSERT_EQ(7, transitionMatrix.getRowGroupIndices()[6]);
 
 	// Test the Markovian states.
 	ASSERT_TRUE(result.markovianStates.get(0));
@@ -69,39 +69,39 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 	ASSERT_FALSE(result.markovianStates.get(5));
 
 	// Test the exit rates. These have to be 0 for all non-Markovian states.
-	ASSERT_EQ(result.exitRates[0], 2);
-	ASSERT_EQ(result.exitRates[1], 0);
-	ASSERT_EQ(result.exitRates[2], 15);
-	ASSERT_EQ(result.exitRates[3], 0);
-	ASSERT_EQ(result.exitRates[4], 0);
-	ASSERT_EQ(result.exitRates[5], 0);
+	ASSERT_EQ(2, result.exitRates[0]);
+	ASSERT_EQ(0, result.exitRates[1]);
+	ASSERT_EQ(15, result.exitRates[2]);
+	ASSERT_EQ(0, result.exitRates[3]);
+	ASSERT_EQ(0, result.exitRates[4]);
+	ASSERT_EQ(0, result.exitRates[5]);
 
 	// Finally, test the transition matrix itself.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
 
-	ASSERT_EQ(cIter->second, 2);
+	ASSERT_EQ(2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 2);
+	ASSERT_EQ(2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 4);
+	ASSERT_EQ(4, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 8);
+	ASSERT_EQ(8, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
 	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
@@ -114,29 +114,29 @@ TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
 	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
 
 	// Build the actual transition matrix.
-	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
+	storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build());
 
 	// Test all sizes and counts.
-	ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
-	ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
-	ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
-	ASSERT_EQ(transitionMatrix.getRowGroupCount(), 6);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices().size(), 7);
-	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
-	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
-	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
-	ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
+	ASSERT_EQ(STATE_COUNT, transitionMatrix.getColumnCount());
+	ASSERT_EQ(CHOICE_COUNT, transitionMatrix.getRowCount());
+	ASSERT_EQ(12, transitionMatrix.getEntryCount());
+	ASSERT_EQ(6, transitionMatrix.getRowGroupCount());
+	ASSERT_EQ(7, transitionMatrix.getRowGroupIndices().size());
+	ASSERT_EQ(CHOICE_COUNT, result.markovianChoices.size());
+	ASSERT_EQ(STATE_COUNT, result.markovianStates.size());
+	ASSERT_EQ(2, result.markovianStates.getNumberOfSetBits());
+	ASSERT_EQ(STATE_COUNT, result.exitRates.size());
 
 	// Test the general structure of the transition system (that will be an Markov automaton).
 
 	// Test the mapping between states and transition matrix rows.
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[0], 0);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[1], 1);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[2], 2);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[3], 3);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[4], 4);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[5], 6);
-	ASSERT_EQ(transitionMatrix.getRowGroupIndices()[6], 7);
+	ASSERT_EQ(0, transitionMatrix.getRowGroupIndices()[0]);
+	ASSERT_EQ(1, transitionMatrix.getRowGroupIndices()[1]);
+	ASSERT_EQ(2, transitionMatrix.getRowGroupIndices()[2]);
+	ASSERT_EQ(3, transitionMatrix.getRowGroupIndices()[3]);
+	ASSERT_EQ(4, transitionMatrix.getRowGroupIndices()[4]);
+	ASSERT_EQ(6, transitionMatrix.getRowGroupIndices()[5]);
+	ASSERT_EQ(7, transitionMatrix.getRowGroupIndices()[6]);
 
 	// Test the Markovian states.
 	ASSERT_TRUE(result.markovianStates.get(0));
@@ -147,39 +147,39 @@ TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
 	ASSERT_FALSE(result.markovianStates.get(5));
 
 	// Test the exit rates. These have to be 0 for all non-Markovian states.
-	ASSERT_EQ(result.exitRates[0], 2);
-	ASSERT_EQ(result.exitRates[1], 0);
-	ASSERT_EQ(result.exitRates[2], 15);
-	ASSERT_EQ(result.exitRates[3], 0);
-	ASSERT_EQ(result.exitRates[4], 0);
-	ASSERT_EQ(result.exitRates[5], 0);
+	ASSERT_EQ(2, result.exitRates[0]);
+	ASSERT_EQ(0, result.exitRates[1]);
+	ASSERT_EQ(15, result.exitRates[2]);
+	ASSERT_EQ(0, result.exitRates[3]);
+	ASSERT_EQ(0, result.exitRates[4]);
+	ASSERT_EQ(0, result.exitRates[5]);
 
 	// Finally, test the transition matrix itself.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
 
-	ASSERT_EQ(cIter->second, 2);
+	ASSERT_EQ(2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 2);
+	ASSERT_EQ(2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 4);
+	ASSERT_EQ(4, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 8);
+	ASSERT_EQ(8, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
 	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
@@ -192,15 +192,15 @@ TEST(MarkovAutomatonSparseTransitionParserTest, FixDeadlocks) {
 	storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock.tra");
 
 	// Test if the result is consistent with the parsed Markov Automaton.
-	storm::storage::SparseMatrix<double> resultMatrix(result.transitionMatrixBuilder.build(0,0));
-	ASSERT_EQ(resultMatrix.getColumnCount(), STATE_COUNT + 1);
-	ASSERT_EQ(resultMatrix.getEntryCount(), 13);
-	ASSERT_EQ(resultMatrix.getRowGroupCount(), 7);
-	ASSERT_EQ(resultMatrix.getRowGroupIndices().size(), 8);
-	ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT +1);
-	ASSERT_EQ(result.markovianStates.size(), STATE_COUNT +1);
-	ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
-	ASSERT_EQ(result.exitRates.size(), STATE_COUNT + 1);
+	storm::storage::SparseMatrix<double> resultMatrix(result.transitionMatrixBuilder.build());
+	ASSERT_EQ(STATE_COUNT + 1, resultMatrix.getColumnCount());
+	ASSERT_EQ(13, resultMatrix.getEntryCount());
+	ASSERT_EQ(7, resultMatrix.getRowGroupCount());
+	ASSERT_EQ(8, resultMatrix.getRowGroupIndices().size());
+	ASSERT_EQ(CHOICE_COUNT +1, result.markovianChoices.size());
+	ASSERT_EQ(STATE_COUNT +1, result.markovianStates.size());
+	ASSERT_EQ(2, result.markovianStates.getNumberOfSetBits());
+	ASSERT_EQ(STATE_COUNT + 1, result.exitRates.size());
 }
 
 TEST(MarkovAutomatonSparseTransitionParserTest, DontFixDeadlocks) {
diff --git a/test/functional/parser/NondeterministicModelParserTest.cpp b/test/functional/parser/NondeterministicModelParserTest.cpp
index cf56975b7..30e4acc61 100644
--- a/test/functional/parser/NondeterministicModelParserTest.cpp
+++ b/test/functional/parser/NondeterministicModelParserTest.cpp
@@ -25,32 +25,32 @@ TEST(NondeterministicModelParserTest, BasicMdpParsing) {
 	// Parse a Mdp and check the result.
 	storm::models::Mdp<double> mdp(storm::parser::NondeterministicModelParser::parseMdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"));
 
-	ASSERT_EQ(mdp.getNumberOfStates(), 6);
-	ASSERT_EQ(mdp.getNumberOfTransitions(), 22);
-	ASSERT_EQ(mdp.getNumberOfChoices(), 11);
+	ASSERT_EQ(6, mdp.getNumberOfStates());
+	ASSERT_EQ(22, mdp.getNumberOfTransitions());
+	ASSERT_EQ(11, mdp.getNumberOfChoices());
 
-	ASSERT_EQ(mdp.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_EQ(2, mdp.getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(mdp.getInitialStates().get(0));
 	ASSERT_TRUE(mdp.getInitialStates().get(4));
-	ASSERT_EQ(mdp.getStateLabeling().getNumberOfAtomicPropositions(), 4);
-	ASSERT_EQ(mdp.getLabelsForState(0).size(), 3);
+	ASSERT_EQ(4, mdp.getStateLabeling().getNumberOfAtomicPropositions());
+	ASSERT_EQ(3, mdp.getLabelsForState(0).size());
 
 	ASSERT_TRUE(mdp.hasStateRewards());
-	ASSERT_EQ(mdp.getStateRewardVector()[0], 0);
-	ASSERT_EQ(mdp.getStateRewardVector()[4], 42);
+	ASSERT_EQ(0, mdp.getStateRewardVector()[0]);
+	ASSERT_EQ(42, mdp.getStateRewardVector()[4]);
 	double rewardSum = 0;
 	for(uint_fast64_t i = 0; i < mdp.getStateRewardVector().size(); i++) {
 		rewardSum += mdp.getStateRewardVector()[i];
 	}
-	ASSERT_EQ(rewardSum, 158.32);
+	ASSERT_EQ(158.32, rewardSum);
 
 	ASSERT_TRUE(mdp.hasTransitionRewards());
-	ASSERT_EQ(mdp.getTransitionRewardMatrix().getEntryCount(), 17);
+	ASSERT_EQ(17, mdp.getTransitionRewardMatrix().getEntryCount());
 	rewardSum = 0;
 	for(uint_fast64_t i = 0; i < mdp.getTransitionRewardMatrix().getRowCount(); i++) {
 			rewardSum += mdp.getTransitionRewardMatrix().getRowSum(i);
 	}
-	ASSERT_EQ(rewardSum, 1376.864);
+	ASSERT_EQ(1376.864, rewardSum);
 }
 
 
@@ -58,24 +58,24 @@ TEST(NondeterministicModelParserTest, BasicCtmdpParsing) {
 	// Parse a Ctmdp and check the result.
 	storm::models::Ctmdp<double> ctmdp(storm::parser::NondeterministicModelParser::parseCtmdp(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/mdp_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew"));
 
-	ASSERT_EQ(ctmdp.getNumberOfStates(), 6);
-	ASSERT_EQ(ctmdp.getNumberOfTransitions(), 22);
-	ASSERT_EQ(ctmdp.getNumberOfChoices(), 11);
+	ASSERT_EQ(6, ctmdp.getNumberOfStates());
+	ASSERT_EQ(22, ctmdp.getNumberOfTransitions());
+	ASSERT_EQ(11, ctmdp.getNumberOfChoices());
 
-	ASSERT_EQ(ctmdp.getInitialStates().getNumberOfSetBits(), 2);
+	ASSERT_EQ(2, ctmdp.getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(ctmdp.getInitialStates().get(0));
 	ASSERT_TRUE(ctmdp.getInitialStates().get(4));
-	ASSERT_EQ(ctmdp.getStateLabeling().getNumberOfAtomicPropositions(), 4);
-	ASSERT_EQ(ctmdp.getLabelsForState(0).size(), 3);
+	ASSERT_EQ(4, ctmdp.getStateLabeling().getNumberOfAtomicPropositions());
+	ASSERT_EQ(3, ctmdp.getLabelsForState(0).size());
 
 	ASSERT_TRUE(ctmdp.hasStateRewards());
-	ASSERT_EQ(ctmdp.getStateRewardVector()[0], 0);
-	ASSERT_EQ(ctmdp.getStateRewardVector()[4], 42);
+	ASSERT_EQ(0, ctmdp.getStateRewardVector()[0]);
+	ASSERT_EQ(42, ctmdp.getStateRewardVector()[4]);
 	double rewardSum = 0;
 	for(uint_fast64_t i = 0; i < ctmdp.getStateRewardVector().size(); i++) {
 		rewardSum += ctmdp.getStateRewardVector()[i];
 	}
-	ASSERT_EQ(rewardSum, 158.32);
+	ASSERT_EQ(158.32, rewardSum);
 
 	ASSERT_TRUE(ctmdp.hasTransitionRewards());
 	ASSERT_EQ(ctmdp.getTransitionRewardMatrix().getEntryCount(), 17);
@@ -83,7 +83,7 @@ TEST(NondeterministicModelParserTest, BasicCtmdpParsing) {
 	for(uint_fast64_t i = 0; i < ctmdp.getTransitionRewardMatrix().getRowCount(); i++) {
 			rewardSum += ctmdp.getTransitionRewardMatrix().getRowSum(i);
 	}
-	ASSERT_EQ(rewardSum, 1376.864);
+	ASSERT_EQ(1376.864, rewardSum);
 }
 
 TEST(NondeterministicModelParserTest, MismatchedFiles) {
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
index 554d689ea..21240a9dd 100644
--- a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -32,87 +32,87 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 	// Test the row mapping, i.e. at which row which state starts.
 	ASSERT_EQ(6, result.getRowGroupCount());
 	ASSERT_EQ(7, result.getRowGroupIndices().size());
-	ASSERT_EQ(result.getRowGroupIndices()[0], 0);
-	ASSERT_EQ(result.getRowGroupIndices()[1], 4);
-	ASSERT_EQ(result.getRowGroupIndices()[2], 5);
-	ASSERT_EQ(result.getRowGroupIndices()[3], 7);
-	ASSERT_EQ(result.getRowGroupIndices()[4], 8);
-	ASSERT_EQ(result.getRowGroupIndices()[5], 9);
-	ASSERT_EQ(result.getRowGroupIndices()[6], 11);
+	ASSERT_EQ(0, result.getRowGroupIndices()[0]);
+	ASSERT_EQ(4, result.getRowGroupIndices()[1]);
+	ASSERT_EQ(5, result.getRowGroupIndices()[2]);
+	ASSERT_EQ(7, result.getRowGroupIndices()[3]);
+	ASSERT_EQ(8, result.getRowGroupIndices()[4]);
+	ASSERT_EQ(9, result.getRowGroupIndices()[5]);
+	ASSERT_EQ(11, result.getRowGroupIndices()[6]);
 
 	// Test the transition matrix.
-	ASSERT_EQ(result.getColumnCount(), 6);
-	ASSERT_EQ(result.getRowCount(), 11);
-	ASSERT_EQ(result.getEntryCount(), 22);
+	ASSERT_EQ(6, result.getColumnCount());
+	ASSERT_EQ(11, result.getRowCount());
+	ASSERT_EQ(22, result.getEntryCount());
 
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
 
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 0.9);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(0.9, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.9);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.9, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.5);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.5, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 0.001);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(0.001, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 0.999);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(0.999, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.7);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.7, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.3);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.3, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0.6);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0.6, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
@@ -121,63 +121,63 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing)
 	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", modelInformation));
 
 	// Test the transition matrix.
-	ASSERT_EQ(result.getColumnCount(), 6);
-	ASSERT_EQ(result.getRowCount(), 11);
-	ASSERT_EQ(result.getEntryCount(), 17);
+	ASSERT_EQ(6, result.getColumnCount());
+	ASSERT_EQ(11, result.getRowCount());
+	ASSERT_EQ(17, result.getEntryCount());
 
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
 
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 30);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(30, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 15.2);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(15.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 75);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(75, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 2.45);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(2.45, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 0);
-	ASSERT_EQ(cIter->second, 0.114);
+	ASSERT_EQ(0, cIter->first);
+	ASSERT_EQ(0.114, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 90);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(90, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 55);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(55, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 87);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(87, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 2);
-	ASSERT_EQ(cIter->second, 13);
+	ASSERT_EQ(2, cIter->first);
+	ASSERT_EQ(13, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 3);
-	ASSERT_EQ(cIter->second, 999);
+	ASSERT_EQ(3, cIter->first);
+	ASSERT_EQ(999, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.7);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.7, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.3);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.3, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.1);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 6);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(6, cIter->second);
 }
 
 TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
@@ -213,37 +213,37 @@ TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
 	// Parse a transitions file with the fixDeadlocks Flag set and test if it works.
 	storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"));
 
-	ASSERT_EQ(result.getRowGroupIndices().size(), 8);
-	ASSERT_EQ(result.getRowGroupIndices()[5], 9);
-	ASSERT_EQ(result.getRowGroupIndices()[6], 10);
-	ASSERT_EQ(result.getRowGroupIndices()[7], 12);
+	ASSERT_EQ(8, result.getRowGroupIndices().size());
+	ASSERT_EQ(9, result.getRowGroupIndices()[5]);
+	ASSERT_EQ(10, result.getRowGroupIndices()[6]);
+	ASSERT_EQ(12, result.getRowGroupIndices()[7]);
 
-	ASSERT_EQ(result.getColumnCount(), 7);
-	ASSERT_EQ(result.getRowCount(), 12);
-	ASSERT_EQ(result.getEntryCount(), 23);
+	ASSERT_EQ(7, result.getColumnCount());
+	ASSERT_EQ(12, result.getRowCount());
+	ASSERT_EQ(23, result.getEntryCount());
 
 	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(8);
 
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.7);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.7, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.3);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.3, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 1);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(1, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 4);
-	ASSERT_EQ(cIter->second, 0.2);
+	ASSERT_EQ(4, cIter->first);
+	ASSERT_EQ(0.2, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 0.6);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(0.6, cIter->second);
 	cIter++;
-	ASSERT_EQ(cIter->first, 5);
-	ASSERT_EQ(cIter->second, 1);
+	ASSERT_EQ(5, cIter->first);
+	ASSERT_EQ(1, cIter->second);
 
 }
 
diff --git a/test/functional/parser/SparseStateRewardParserTest.cpp b/test/functional/parser/SparseStateRewardParserTest.cpp
index 2b6462ca0..7a1d9120c 100644
--- a/test/functional/parser/SparseStateRewardParserTest.cpp
+++ b/test/functional/parser/SparseStateRewardParserTest.cpp
@@ -36,7 +36,7 @@ TEST(SparseStateRewardParserTest, BasicParsing) {
 
 	// Now test if the correct value were parsed.
 	for(int i = 0; i < 100; i++) {
-		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
+		ASSERT_EQ(std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7), std::round(result[i]));
 	}
 }
 
@@ -47,7 +47,7 @@ TEST(SparseStateRewardParserTest, Whitespaces) {
 
 	// Now test if the correct value were parsed.
 	for(int i = 0; i < 100; i++) {
-		ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
+		ASSERT_EQ(std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7), std::round(result[i]));
 	}
 }
 

From 2ed6be853b5d71c6c7eabe1cb3b62d0d7d2e60ed Mon Sep 17 00:00:00 2001
From: masawei <manuel.sascha.weiand@rwth-aachen.de>
Date: Sun, 16 Mar 2014 00:08:25 +0100
Subject: [PATCH 024/147] Fixed two minor bugs.

- First one concerning the MappedFileTest in which I neglected to consider that the number of characters used to signal a new line differs between Linux (\n -> 1) and Windows (\r\n -> 2) which caused the test to fail on all OS using two characters (hence not on Linux, where I ran the tests).
- Second bug concerned the case that a transition reward file contained more states than the corresponding transition file.
  In that case the parser tried to acces the entry of the rowGroupIndices vector behind the last actual entry, which caused an exception to be thrown.
  Now there is a check whether the highest state index found by the parser does exceed the highest state index of the model.


Former-commit-id: bc83267f3ce03a53d03485ce703306c40294383c
---
 .../NondeterministicSparseTransitionParser.cpp   |  7 +++++++
 test/functional/parser/MappedFileTest.cpp        | 16 +++++++++++-----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 7d6fbb527..32557dbb2 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -238,6 +238,13 @@ namespace storm {
 				}
 
 				if (isRewardFile) {
+
+					// Make sure that the highest state index of the reward file is not higher than the highest state index of the corresponding model.
+					if(result.highestStateIndex > modelInformation.getColumnCount() - 1) {
+						LOG4CPLUS_ERROR(logger, "State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " .");
+						throw storm::exceptions::OutOfRangeException() << "State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " .";
+					}
+
 					// If we have switched the source state, we possibly need to insert rows for skipped choices of the last
 					// source state.
 					if (source != lastSource) {
diff --git a/test/functional/parser/MappedFileTest.cpp b/test/functional/parser/MappedFileTest.cpp
index a86ecb7cc..8b4d7bfba 100644
--- a/test/functional/parser/MappedFileTest.cpp
+++ b/test/functional/parser/MappedFileTest.cpp
@@ -10,6 +10,7 @@
 
 #include <string>
 #include "src/parser/MappedFile.h"
+#include "src/utility/cstring.h"
 #include "src/exceptions/FileIoException.h"
 
 TEST(MappedFileTest, NonExistingFile) {
@@ -21,13 +22,18 @@ TEST(MappedFileTest, BasicFunctionality) {
 
 	// Open a file and test if the content is loaded as expected.
 	storm::parser::MappedFile file(STORM_CPP_TESTS_BASE_PATH "/functional/parser/testStringFile.txt");
-	std::string testString = "This is a test string.\n";
-	ASSERT_EQ(testString.length(), file.getDataEnd() - file.getData());
-	char const * testStringPtr = testString.c_str();
-	for(char* dataPtr = file.getData(); dataPtr < file.getDataEnd(); dataPtr++) {
+	std::string testString = "This is a test string.";
+	char * dataPtr = file.getData();
+	for(char const * testStringPtr = testString.c_str(); testStringPtr - testString.c_str() < 22; testStringPtr++) {
 		ASSERT_EQ(*testStringPtr, *dataPtr);
-		testStringPtr++;
+		dataPtr++;
 	}
+	// The next character should be an end of line character (actual character varies between operating systems).
+	ASSERT_EQ(dataPtr, storm::utility::cstring::forwardToLineEnd(dataPtr));
+
+	// The newline character should be the last contained in the string.
+	ASSERT_EQ(file.getDataEnd(), storm::utility::cstring::forwardToNextLine(dataPtr));
+
 }
 
 TEST(MappedFileTest, ExistsAndReadble) {

From de44a1562ce9f82302cdba7fa5c96c901d919e4b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 19 Mar 2014 23:24:55 +0100
Subject: [PATCH 025/147] Started writing the DD abstraction layer.

Former-commit-id: 8720a38b17b919f2e7ea33f57bb2e513edf8d210
---
 CMakeLists.txt                                |   4 +-
 CPackConfig.cmake                             |  27 ----
 .../MILPMinimalLabelSetGenerator.h            |   2 +-
 src/storage/dd/CuddDd.h                       | 126 ++++++++++++++++++
 src/storage/dd/CuddDdManager.cpp              |   7 +
 src/storage/dd/CuddDdManager.h                |  98 ++++++++++++++
 src/storage/dd/Dd.h                           |  13 ++
 src/storage/dd/DdManager.h                    |  13 ++
 src/storage/dd/DdMetaVariable.cpp             |  38 ++++++
 src/storage/dd/DdMetaVariable.h               | 101 ++++++++++++++
 10 files changed, 400 insertions(+), 29 deletions(-)
 delete mode 100644 CPackConfig.cmake
 create mode 100644 src/storage/dd/CuddDd.h
 create mode 100644 src/storage/dd/CuddDdManager.cpp
 create mode 100644 src/storage/dd/CuddDdManager.h
 create mode 100644 src/storage/dd/Dd.h
 create mode 100644 src/storage/dd/DdManager.h
 create mode 100644 src/storage/dd/DdMetaVariable.cpp
 create mode 100644 src/storage/dd/DdMetaVariable.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa1e269c0..8942c984f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -242,7 +242,8 @@ file(GLOB STORM_PARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/*.h ${PROJECT_SOUR
 file(GLOB_RECURSE STORM_PARSER_PRISMPARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/prismparser/*.h ${PROJECT_SOURCE_DIR}/src/parser/prismparser/*.cpp)
 file(GLOB_RECURSE STORM_SETTINGS_FILES ${PROJECT_SOURCE_DIR}/src/settings/*.h ${PROJECT_SOURCE_DIR}/src/settings/*.cpp)
 file(GLOB_RECURSE STORM_SOLVER_FILES ${PROJECT_SOURCE_DIR}/src/solver/*.h ${PROJECT_SOURCE_DIR}/src/solver/*.cpp)
-file(GLOB_RECURSE STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp)
+file(GLOB STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp)
+file(GLOB_RECURSE STORM_STORAGE_DD_FILES ${PROJECT_SOURCE_DIR}/src/storage/dd/*.h ${PROJECT_SOURCE_DIR}/src/storage/dd/*.cpp)
 file(GLOB_RECURSE STORM_UTILITY_FILES ${PROJECT_SOURCE_DIR}/src/utility/*.h ${PROJECT_SOURCE_DIR}/src/utility/*.cpp)
 file(GLOB STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp)
 file(GLOB_RECURSE STORM_IR_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.h ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.cpp)
@@ -275,6 +276,7 @@ source_group(parser\\prismparser FILES ${STORM_PARSER_PRISMPARSER_FILES})
 source_group(settings FILES ${STORM_SETTINGS_FILES})
 source_group(solver FILES ${STORM_SOLVER_FILES})
 source_group(storage FILES ${STORM_STORAGE_FILES})
+source_group(storage\\dd FILES ${STORM_STORAGE_DD_FILES})
 source_group(utility FILES ${STORM_UTILITY_FILES})
 source_group(functional-test FILES ${STORM_FUNCTIONAL_TEST_FILES})
 source_group(performance-test FILES ${STORM_PERFORMANCE_TEST_FILES})
diff --git a/CPackConfig.cmake b/CPackConfig.cmake
deleted file mode 100644
index 5ce6c0f53..000000000
--- a/CPackConfig.cmake
+++ /dev/null
@@ -1,27 +0,0 @@
-include(InstallRequiredSystemLibraries)
-
-# For help take a look at:
-# http://www.cmake.org/Wiki/CMake:CPackConfiguration
-
-### general settings
-set(CPACK_PACKAGE_NAME "StoRM")
-set(CPACK_PACKAGE_VENDOR "i2 RWTH Aachen University")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Stochastic Reward Model Checker - An extensible model checker written in C++.")
-
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
-
-### versions
-set(CPACK_PACKAGE_VERSION_MAJOR "${STORM_CPP_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${STORM_CPP_VERSION_MINOR}")
-set(CPACK_PACKAGE_VERSION_PATCH "${STORM_CPP_VERSION_PATCH}")
-set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${STORM_CPP_VERSION_HASH}")
-
-set(CPACK_GENERATOR "ZIP")
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
-
-### source package settings
-set(CPACK_SOURCE_GENERATOR "ZIP")
-set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src")
-
-include(CPack)
\ No newline at end of file
diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index 3ec8256ed..027369182 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -1021,7 +1021,7 @@ namespace storm {
                     LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation.");
                     throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation.";
                 }
-                bool strictBound = !probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS;
+                bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS);
 
                 // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape.
                 double bound = probBoundFormula->getBound();
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
new file mode 100644
index 000000000..d608b07e5
--- /dev/null
+++ b/src/storage/dd/CuddDd.h
@@ -0,0 +1,126 @@
+#ifndef STORM_STORAGE_DD_CUDDDD_H_
+#define STORM_STORAGE_DD_CUDDDD_H_
+
+#include "src/storage/dd/Dd.h"
+#include "src/storage/dd/CuddDdManager.h"
+
+// Include the C++-interface of CUDD.
+#include "cuddObj.hh"
+
+namespace storm {
+    namespace dd {
+        
+        template<>
+        class Dd<CUDD> {
+            /*!
+             * Creates a DD that encapsulates the given CUDD ADD.
+             *
+             * @param cuddAdd The CUDD ADD to store.
+             */
+            Dd(ADD cuddAdd);
+            
+            // Instantiate all copy/move constructors/assignments with the default implementation.
+            Dd(Dd<CUDD> const& other) = default;
+            Dd(Dd<CUDD>&& other) = default;
+            Dd& operator=(Dd<CUDD> const& other) = default;
+            Dd& operator=(Dd<CUDD>&& other) = default;
+            
+            /*!
+             * Adds the two DDs.
+             *
+             * @param other The DD to add to the current one.
+             * @return The result of the addition.
+             */
+            Dd<CUDD> operator+(Dd<CUDD> const& other) const;
+
+            /*!
+             * Adds the given DD to the current one.
+             *
+             * @param other The DD to add to the current one.
+             * @return A reference to the current DD after the operation.
+             */
+            Dd<CUDD>& operator+=(Dd<CUDD> const& other);
+            
+            /*!
+             * Multiplies the two DDs.
+             *
+             * @param other The DD to multiply with the current one.
+             * @return The result of the multiplication.
+             */
+            Dd<CUDD> operator*(Dd<CUDD> const& other) const;
+
+            /*!
+             * Multiplies the given DD with the current one and assigns the result to the current DD.
+             *
+             * @param other The DD to multiply with the current one.
+             * @return A reference to the current DD after the operation.
+             */
+            Dd<CUDD>& operator*=(Dd<CUDD> const& other);
+            
+            /*!
+             * Subtracts the given DD from the current one.
+             *
+             * @param other The DD to subtract from the current one.
+             * @return The result of the subtraction.
+             */
+            Dd<CUDD> operator-(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Subtracts the given DD from the current one and assigns the result to the current DD.
+             *
+             * @param other The DD to subtract from the current one.
+             * @return A reference to the current DD after the operation.
+             */
+            Dd<CUDD>& operator-=(Dd<CUDD> const& other);
+            
+            /*!
+             * Divides the current DD by the given one.
+             *
+             * @param other The DD by which to divide the current one.
+             * @return The result of the division.
+             */
+            Dd<CUDD> operator/(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Divides the current DD by the given one and assigns the result to the current DD.
+             *
+             * @param other The DD by which to divide the current one.
+             * @return A reference to the current DD after the operation.
+             */
+            Dd<CUDD>& operator/=(Dd<CUDD> const& other);
+            
+            /*!
+             * Retrieves the logical complement of the current DD. The result will map all encodings with a value
+             * unequal to zero to false and all others to true.
+             *
+             * @return The logical complement of the current DD.
+             */
+            Dd<CUDD> operator~() const;
+            
+            /*!
+             * Logically complements the current DD. The result will map all encodings with a value
+             * unequal to zero to false and all others to true.
+             */
+            void complement();
+            
+            /*!
+             * Retrieves the manager that is responsible for this DD.
+             *
+             * A pointer to the manager that is responsible for this DD.
+             */
+            std::shared_ptr<DdManager<CUDD>> getDdManager() const;
+            
+        private:
+            // A pointer to the manager responsible for this DD.
+            std::shared_ptr<DdManager<CUDD>> ddManager;
+
+            // The ADD created by CUDD.
+            ADD cuddAdd;
+            
+            // The names of all meta variables that appear in this DD.
+            std::unordered_set<std::string> containedMetaVariableNames;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_CUDDDD_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
new file mode 100644
index 000000000..af75ca402
--- /dev/null
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -0,0 +1,7 @@
+#include "src/storage/dd/CuddDdManager.h"
+
+namespace storm {
+    namespace dd {
+        
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
new file mode 100644
index 000000000..8c47b4b2d
--- /dev/null
+++ b/src/storage/dd/CuddDdManager.h
@@ -0,0 +1,98 @@
+#ifndef STORM_STORAGE_DD_CUDDDDMANAGER_H_
+#define STORM_STORAGE_DD_CUDDDDMANAGER_H_
+
+#include <unordered_set>
+#include <unordered_map>
+
+#include "src/storage/dd/DdManager.h"
+
+// Include the C++-interface of CUDD.
+#include "cuddObj.hh"
+
+namespace storm {
+    namespace dd {
+        // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
+        template<DdType Type> class DdMetaVariable;
+        template<DdType Type> class Dd;
+        
+        template<>
+        class DdManager<CUDD> : std::enable_shared_from_this<DdManager<CUDD>> {
+            /*!
+             * Creates an empty manager without any meta variables.
+             */
+            DdManager();
+            
+            // Explictly forbid copying a DdManager, but allow moving it.
+            DdManager(DdManager<CUDD> const& other) = delete;
+            DdManager(DdManager<CUDD>&& other) = default;
+            DdManager<CUDD>& operator=(DdManager<CUDD> const& other) = delete;
+            DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
+            
+            /*!
+             * Retrieves a DD representing the constant one function.
+             *
+             * @return A DD representing the constant one function.
+             */
+            Dd<CUDD> getOne();
+            
+            /*!
+             * Retrieves a DD representing the constant zero function.
+             *
+             * @return A DD representing the constant zero function.
+             */
+            Dd<CUDD> getZero();
+            
+            /*!
+             * Retrieves a DD representing the constant function with the given value.
+             *
+             * @return A DD representing the constant function with the given value.
+             */
+            Dd<CUDD> getConstant(double value);
+
+            /*!
+             * Adds a meta variable with the given name and range.
+             *
+             * @param name The name of the meta variable.
+             * @param low The lowest value of the range of the variable.
+             * @param high The highest value of the range of the variable.
+             * @param addSuccessorVariable If set, a second meta variable is added. This can then be used, for example,
+             * to encode the value of the meta variable in a successor state.
+             * @param useInterleavedVariableOrdering If set, the variables used for the successor meta variable are
+             * interleaved with the ones for the added meta variable.
+             */
+            void addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, bool addSuccessorVariable = false, bool useInterleavedVariableOrdering = true);
+            
+            /*!
+             * Retrieves the meta variable with the given name if it exists.
+             *
+             * @param metaVariableName The name of the meta variable to retrieve.
+             * @return The meta variable with the given name.
+             */
+            DdMetaVariable<CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
+            
+            /*!
+             * Retrieves the successor meta variable of the one with the given name if it exists.
+             *
+             * @param metaVariableName The name of the meta variable whose successor meta variable to retrieve.
+             * @return The successor meta variable of the one with the given name.
+             */
+            DdMetaVariable<CUDD> const& getSuccessorMetaVariable(std::string const& metaVariableName) const;
+            
+            /*!
+             * Retrieves the names of all meta variables that have been added to the manager.
+             *
+             * @return The set of all meta variable names of the manager.
+             */
+            std::unordered_set<std::string> getAllMetaVariableNames();
+            
+        private:
+            // A mapping from variable names to the meta variable information.
+            std::unordered_map<std::string, DdMetaVariable<CUDD>> metaVariableMap;
+            
+            // The manager responsible for the DDs created/modified with this DdManager.
+            Cudd cuddManager;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_CUDDDDMANAGER_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/Dd.h b/src/storage/dd/Dd.h
new file mode 100644
index 000000000..bc7075f46
--- /dev/null
+++ b/src/storage/dd/Dd.h
@@ -0,0 +1,13 @@
+#ifndef STORM_STORAGE_DD_DD_H_
+#define STORM_STORAGE_DD_DD_H_
+
+#include "src/storage/dd/DdType.h"
+
+namespace storm {
+    namespace dd {
+        // Declare Dd class so we can then specialize it for the different DD types.
+        template<DdType Type> class Dd;
+    }
+}
+
+#endif /* STORM_STORAGE_DD_DD_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/DdManager.h b/src/storage/dd/DdManager.h
new file mode 100644
index 000000000..53fde64bb
--- /dev/null
+++ b/src/storage/dd/DdManager.h
@@ -0,0 +1,13 @@
+#ifndef STORM_STORAGE_DD_DDMANAGER_H_
+#define STORM_STORAGE_DD_DDMANAGER_H_
+
+#include "src/storage/dd/DdType.h"
+
+namespace storm {
+    namespace dd {
+        // Declare DdManager class so we can then specialize it for the different DD types.
+        template<DdType Type> class DdManager;
+    }
+}
+
+#endif /* STORM_STORAGE_DD_DDMANAGER_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
new file mode 100644
index 000000000..72c2be15f
--- /dev/null
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -0,0 +1,38 @@
+#include "src/storage/dd/DdMetaVariable.h"
+
+namespace storm {
+    namespace dd {
+        template<DdType Type>
+        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), low(low), high(high), ddVariables(ddVariables), manager(manager) {
+            // Intentionally left empty.
+        }
+        
+        template<DdType Type>
+        std::string const& DdMetaVariable<Type>::getName() const {
+            return this->name;
+        }
+        
+        template<DdType Type>
+        int_fast64_t DdMetaVariable<Type>::getLow() const {
+            return this->low;
+        }
+
+        template<DdType Type>
+        int_fast64_t DdMetaVariable<Type>::getHigh() const {
+            return this->high;
+        }
+
+        template<DdType Type>
+        std::vector<Dd<Type>> const& DdMetaVariable<Type>::getDdVariables() const {
+            return this->ddVariables;
+        }
+        
+        template<DdType Type>
+        Dd<Type> const& DdMetaVariable<Type>::getCube() const {
+            return this->cube;
+        }
+        
+        // Explicitly instantiate DdMetaVariable.
+        template<> class DdMetaVariable<CUDD>;
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
new file mode 100644
index 000000000..2631143f2
--- /dev/null
+++ b/src/storage/dd/DdMetaVariable.h
@@ -0,0 +1,101 @@
+#ifndef STORM_STORAGE_DD_DDMETAVARIABLE_H_
+#define STORM_STORAGE_DD_DDMETAVARIABLE_H_
+
+#include <memory>
+#include <vector>
+#include <cstdint>
+#include <string>
+
+#include "src/storage/dd/CuddDdManager.h"
+#include "src/storage/dd/CuddDd.h"
+
+namespace storm {
+    namespace dd {
+        
+        template <DdType Type>
+        class DdMetaVariable {
+            // Declare the other DD-related classes as friends so they can access the internals of a meta variable.
+            friend class Dd<Type>;
+            
+            /*!
+             * Creates a meta variable with the given name, range bounds.
+             *
+             * @param name The name of the meta variable.
+             * @param low The lowest value of the range of the variable.
+             * @param high The highest value of the range of the variable.
+             * @param ddVariables The vector of variables used to encode this variable.
+             * @param manager A pointer to the manager that is responsible for this meta variable.
+             */
+            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
+            
+            // Explictly generate all default versions of copy/move constructors/assignments.
+            DdMetaVariable(DdMetaVariable const& other) = default;
+            DdMetaVariable(DdMetaVariable&& other) = default;
+            DdMetaVariable& operator=(DdMetaVariable const& other) = default;
+            DdMetaVariable& operator=(DdMetaVariable&& other) = default;
+            
+            /*!
+             * Retrieves the name of the meta variable.
+             *
+             * @return The name of the variable.
+             */
+            std::string const& getName() const;
+            
+            /*!
+             * Retrieves the lowest value of the range of the variable.
+             *
+             * @return The lowest value of the range of the variable.
+             */
+            int_fast64_t getLow() const;
+
+            /*!
+             * Retrieves the highest value of the range of the variable.
+             *
+             * @return The highest value of the range of the variable.
+             */
+            int_fast64_t getHigh() const;
+
+            /*!
+             * Retrieves the manager that is responsible for this meta variable.
+             *
+             * A pointer to the manager that is responsible for this meta variable.
+             */
+            std::shared_ptr<DdManager<Type>> getDdManager() const;
+            
+        private:
+            /*!
+             * Retrieves the variables used to encode the meta variable.
+             *
+             * @return A vector of variables used to encode the meta variable.
+             */
+            std::vector<Dd<Type>> const& getDdVariables() const;
+            
+            /*!
+             * Retrieves the cube of all variables that encode this meta variable.
+             *
+             * @return The cube of all variables that encode this meta variable.
+             */
+            Dd<Type> const& getCube() const;
+
+            // The name of the meta variable.
+            std::string name;
+            
+            // The lowest value of the range of the variable.
+            int_fast64_t low;
+            
+            // The highest value of the range of the variable.
+            int_fast64_t high;
+            
+            // The vector of variables that are used to encode the meta variable.
+            std::vector<Dd<Type>> ddVariables;
+            
+            // The cube consisting of all variables that encode the meta variable.
+            Dd<Type> cube;
+            
+            // A pointer to the manager responsible for this meta variable.
+            std::shared_ptr<DdManager<Type>> manager;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_DDMETAVARIABLE_H_ */
\ No newline at end of file

From 70fc3ec29a76958717b36b341cfb80d3673442c8 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 20 Mar 2014 18:50:30 +0100
Subject: [PATCH 026/147] Further work on abstraction layer for DDs.

Former-commit-id: 245986076bca9c24016c8d6f6ab487438f3ed008
---
 src/storage/dd/CuddDd.cpp         |  90 +++++++++++++++
 src/storage/dd/CuddDd.h           | 178 ++++++++++++++++++++++++++++--
 src/storage/dd/CuddDdManager.cpp  |  68 ++++++++++++
 src/storage/dd/CuddDdManager.h    |  42 ++++---
 src/storage/dd/DdMetaVariable.cpp |  13 ++-
 src/storage/dd/DdMetaVariable.h   |   6 +-
 src/storage/dd/DdType.h           |  12 ++
 7 files changed, 378 insertions(+), 31 deletions(-)
 create mode 100644 src/storage/dd/CuddDd.cpp
 create mode 100644 src/storage/dd/DdType.h

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
new file mode 100644
index 000000000..d3ad10493
--- /dev/null
+++ b/src/storage/dd/CuddDd.cpp
@@ -0,0 +1,90 @@
+#include "src/storage/dd/CuddDd.h"
+
+namespace storm {
+    namespace dd {
+        Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
+            // Intentionally left empty.
+        }
+        
+        Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result += other;
+            return result;
+        }
+        
+        Dd<CUDD>& Dd<CUDD>::operator+=(Dd<CUDD> const& other) {
+            cuddAdd += other;
+            
+            // Join the variable sets of the two participating DDs.
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            
+            return *this;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::operator*(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result *= other;
+            return result;
+        }
+        
+        Dd<CUDD>& Dd<CUDD>::operator*=(Dd<CUDD> const& other) {
+            cuddAdd *= other;
+            
+            // Join the variable sets of the two participating DDs.
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            
+            return *this;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::operator-(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result -= other;
+            return result;
+        }
+        
+        Dd<CUDD>& Dd<CUDD>::operator-=(Dd<CUDD> const& other) {
+            cuddAdd -= other;
+            
+            // Join the variable sets of the two participating DDs.
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            
+            return *this;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::operator/(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result /= other;
+            return result;
+        }
+        
+        Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
+            cuddAdd.Divide(other);
+            
+            // Join the variable sets of the two participating DDs.
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            
+            return *this;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::operator~() const {
+            Dd<CUDD> result(*this);
+            result.complement();
+            return result;
+        }
+        
+        Dd<CUDD>& Dd<CUDD>::complement() {
+            cuddAdd = ~cuddAdd;
+            return *this;
+        }
+        
+        void Dd<CUDD>::exportToDot(std::string const& filename) const {
+            FILE* filePointer = fopen(filename.c_str() , "w");
+            this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer);
+            fclose(filePointer);
+        }
+        
+        std::shared_ptr<DdManager<CUDD>> Dd<CUDD>::getDdManager() const {
+            return this->ddManager;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index d608b07e5..eff759bd3 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -12,13 +12,10 @@ namespace storm {
         
         template<>
         class Dd<CUDD> {
-            /*!
-             * Creates a DD that encapsulates the given CUDD ADD.
-             *
-             * @param cuddAdd The CUDD ADD to store.
-             */
-            Dd(ADD cuddAdd);
-            
+        public:
+            // Declare the DdManager class as friend so it can access the internals of a DD.
+            friend class DdManager<CUDD>;
+
             // Instantiate all copy/move constructors/assignments with the default implementation.
             Dd(Dd<CUDD> const& other) = default;
             Dd(Dd<CUDD>&& other) = default;
@@ -89,6 +86,13 @@ namespace storm {
              */
             Dd<CUDD>& operator/=(Dd<CUDD> const& other);
             
+            /*!
+             * Subtracts the DD from the constant zero function.
+             *
+             * @return The resulting function represented as a DD.
+             */
+            Dd<CUDD> minus() const;
+            
             /*!
              * Retrieves the logical complement of the current DD. The result will map all encodings with a value
              * unequal to zero to false and all others to true.
@@ -100,8 +104,157 @@ namespace storm {
             /*!
              * Logically complements the current DD. The result will map all encodings with a value
              * unequal to zero to false and all others to true.
+             *
+             * @return A reference to the current DD after the operation.
+             */
+            Dd<CUDD>& complement();
+            
+            /*!
+             * Retrieves the function that maps all evaluations to one that have an identical function values.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<CUDD> equals(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Retrieves the function that maps all evaluations to one that have distinct function values.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<CUDD> notEquals(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Retrieves the function that maps all evaluations to one whose function value in the first DD are less
+             * than the one in the given DD.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<CUDD> less(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Retrieves the function that maps all evaluations to one whose function value in the first DD are less or
+             * equal than the one in the given DD.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<CUDD> lessOrEqual(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
+             * than the one in the given DD.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
              */
-            void complement();
+            Dd<CUDD> greater(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
+             * or equal than the one in the given DD.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<CUDD> greaterOrEqual(Dd<CUDD> const& other) const;
+            
+            /*!
+             * Existentially abstracts from the given meta variables.
+             *
+             * @param metaVariableNames The names of all meta variables from which to abstract.
+             */
+            void existsAbstract(std::unordered_set<std::string> const& metaVariableNames);
+
+            /*!
+             * Sum-abstracts from the given meta variables.
+             *
+             * @param metaVariableNames The names of all meta variables from which to abstract.
+             */
+            void sumAbstract(std::unordered_set<std::string> const& metaVariableNames);
+            
+            /*!
+             * Min-abstracts from the given meta variables.
+             *
+             * @param metaVariableNames The names of all meta variables from which to abstract.
+             */
+            void minAbstract(std::unordered_set<std::string> const& metaVariableNames);
+            
+            /*!
+             * Max-abstracts from the given meta variables.
+             *
+             * @param metaVariableNames The names of all meta variables from which to abstract.
+             */
+            void maxAbstract(std::unordered_set<std::string> const& metaVariableNames);
+
+            /*!
+             * Sets the function values of all encodings that have the given value of the meta variable to the given
+             * target value.
+             *
+             * @param metaVariableName The name of the meta variable that has to be equal to the given value.
+             * @param variableValue The value that the meta variable is supposed to have. This must be within the range
+             * of the meta variable.
+             * @param targetValue The new function value of the modified encodings.
+             */
+            void setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue);
+
+            /*!
+             * Sets the function values of all encodings that have the given values of the two meta variables to the
+             * given target value.
+             *
+             * @param metaVariableName1 The name of the first meta variable that has to be equal to the first given
+             * value.
+             * @param variableValue1 The value that the first meta variable is supposed to have. This must be within the
+             * range of the meta variable.
+             * @param metaVariableName2 The name of the first meta variable that has to be equal to the second given
+             * value.
+             * @param variableValue2 The value that the second meta variable is supposed to have. This must be within
+             * the range of the meta variable.
+             * @param targetValue The new function value of the modified encodings.
+             */
+            void setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue);
+            
+            /*!
+             * Sets the function values of all encodings that have the given values of the given meta variables to the
+             * given target value.
+             *
+             * @param metaVariableNameToValueMap A mapping of meta variable names to the values they are supposed to
+             * have. All values must be within the range of the respective meta variable.
+             * @param targetValue The new function value of the modified encodings.
+             */
+            void setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
+            
+            /*!
+             * Retrieves whether the given meta variable is contained in the DD.
+             *
+             * @param metaVariableName The name of the meta variable for which to query membership.
+             * @return True iff the meta variable is contained in the DD.
+             */
+            bool containsMetaVariable(std::string const& metaVariableName) const;
+            
+            /*!
+             * Retrieves whether the given meta variables are all contained in the DD.
+             *
+             * @param metaVariableNames The names of the meta variable for which to query membership.
+             * @return True iff all meta variables are contained in the DD.
+             */
+            bool containsMetaVariables(std::unordered_set<std::string> metaVariableNames) const;
+            
+            /*!
+             * Retrieves the set of all names of meta variables contained in the DD.
+             *
+             * @return The set of names of all meta variables contained in the DD.
+             */
+            std::unordered_set<std::string> const& getContainedMetaVariableNames() const;
+            
+            /*!
+             * Exports the DD to the given file in the dot format.
+             *
+             * @param filename The name of the file to which the DD is to be exported.
+             */
+            void exportToDot(std::string const& filename) const;
             
             /*!
              * Retrieves the manager that is responsible for this DD.
@@ -111,6 +264,15 @@ namespace storm {
             std::shared_ptr<DdManager<CUDD>> getDdManager() const;
             
         private:
+            /*!
+             * Creates a DD that encapsulates the given CUDD ADD.
+             *
+             * @param ddManager The manager responsible for this DD.
+             * @param cuddAdd The CUDD ADD to store.
+             * @param
+             */
+            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept;
+            
             // A pointer to the manager responsible for this DD.
             std::shared_ptr<DdManager<CUDD>> ddManager;
 
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index af75ca402..580c6c9a6 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -1,7 +1,75 @@
 #include "src/storage/dd/CuddDdManager.h"
+#include "src/exceptions/InvalidArgumentException.h"
 
 namespace storm {
     namespace dd {
+        DdManager<CUDD>::DdManager() noexcept : metaVariableMap(), cuddManager() {
+            // Intentionally left empty.
+        }
         
+        Dd<CUDD> DdManager<CUDD>::getOne() {
+            return Dd<CUDD>(this->shared_from_this(), cuddManager.addOne(), {""});
+        }
+        
+        Dd<CUDD> DdManager<CUDD>::getZero() {
+            return Dd<CUDD>(this->shared_from_this(), cuddManager.addZero(), {""});
+        }
+        
+        Dd<CUDD> DdManager<CUDD>::getConstant(double value) {
+            return Dd<CUDD>(this->shared_from_this(), cuddManager.constant(value), {""});
+        }
+
+        void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
+            std::size_t numberOfBits = std::log2(high - low);
+            
+            std::vector<Dd<CUDD>> variables;
+            for (std::size_t i = 0; i < numberOfBits; ++i) {
+                variables.emplace_back(cuddManager.addVar());
+            }
+            
+            metaVariableMap.emplace(name, low, high, variables, this->shared_from_this());
+        }
+        
+        void DdManager<CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
+            if (names.size() == 0) {
+                throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables.";
+            }
+            
+            // Add the variables in interleaved order.
+            std::size_t numberOfBits = std::log2(high - low);
+            std::vector<std::vector<Dd<CUDD>>> variables;
+            for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
+                for (uint_fast64_t i = 0; i < names.size(); ++i) {
+                    variables[i].emplace_back(cuddManager.addVar());
+                }
+            }
+            
+            // Now add the meta variables.
+            for (uint_fast64_t i = 0; i < names.size(); ++i) {
+                metaVariableMap.emplace(names[i], low, high, variables[i], this->shared_from_this());
+            }
+        }
+        
+        DdMetaVariable<CUDD> const& DdManager<CUDD>::getMetaVariable(std::string const& metaVariableName) const {
+            auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
+            
+            if (nameVariablePair == metaVariableMap.end()) {
+                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name.";
+            }
+            
+            return nameVariablePair->second;
+        }
+        
+        std::unordered_set<std::string> DdManager<CUDD>::getAllMetaVariableNames() const {
+            std::unordered_set<std::string> result;
+            for (auto const& nameValuePair : metaVariableMap) {
+                result.insert(nameValuePair.first);
+            }
+            return result;
+        }
+        
+        Cudd& DdManager<CUDD>::getCuddManager() {
+            return this->cuddManager;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 8c47b4b2d..72f2aea0c 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -5,22 +5,24 @@
 #include <unordered_map>
 
 #include "src/storage/dd/DdManager.h"
+#include "src/storage/dd/DdMetaVariable.h"
+#include "src/storage/dd/CuddDd.h"
 
 // Include the C++-interface of CUDD.
 #include "cuddObj.hh"
 
 namespace storm {
     namespace dd {
-        // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
-        template<DdType Type> class DdMetaVariable;
-        template<DdType Type> class Dd;
-        
         template<>
         class DdManager<CUDD> : std::enable_shared_from_this<DdManager<CUDD>> {
+            // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
+            friend class DdMetaVariable<CUDD>;
+            friend class Dd<CUDD>;
+
             /*!
              * Creates an empty manager without any meta variables.
              */
-            DdManager();
+            DdManager() noexcept;
             
             // Explictly forbid copying a DdManager, but allow moving it.
             DdManager(DdManager<CUDD> const& other) = delete;
@@ -55,12 +57,17 @@ namespace storm {
              * @param name The name of the meta variable.
              * @param low The lowest value of the range of the variable.
              * @param high The highest value of the range of the variable.
-             * @param addSuccessorVariable If set, a second meta variable is added. This can then be used, for example,
-             * to encode the value of the meta variable in a successor state.
-             * @param useInterleavedVariableOrdering If set, the variables used for the successor meta variable are
-             * interleaved with the ones for the added meta variable.
              */
-            void addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, bool addSuccessorVariable = false, bool useInterleavedVariableOrdering = true);
+            void addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high);
+            
+            /*!
+             * Adds meta variables with the given names and (equal) range and arranges the DD variables in an interleaved order.
+             *
+             * @param names The names of the variables.
+             * @param low The lowest value of the ranges of the variables.
+             * @param high The highest value of the ranges of the variables.
+             */
+            void addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high);
             
             /*!
              * Retrieves the meta variable with the given name if it exists.
@@ -71,21 +78,20 @@ namespace storm {
             DdMetaVariable<CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
             
             /*!
-             * Retrieves the successor meta variable of the one with the given name if it exists.
+             * Retrieves the names of all meta variables that have been added to the manager.
              *
-             * @param metaVariableName The name of the meta variable whose successor meta variable to retrieve.
-             * @return The successor meta variable of the one with the given name.
+             * @return The set of all meta variable names of the manager.
              */
-            DdMetaVariable<CUDD> const& getSuccessorMetaVariable(std::string const& metaVariableName) const;
+            std::unordered_set<std::string> getAllMetaVariableNames() const;
             
+        private:
             /*!
-             * Retrieves the names of all meta variables that have been added to the manager.
+             * Retrieves the underlying CUDD manager.
              *
-             * @return The set of all meta variable names of the manager.
+             * @return The underlying CUDD manager.
              */
-            std::unordered_set<std::string> getAllMetaVariableNames();
+            Cudd& getCuddManager();
             
-        private:
             // A mapping from variable names to the meta variable information.
             std::unordered_map<std::string, DdMetaVariable<CUDD>> metaVariableMap;
             
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
index 72c2be15f..c2795562b 100644
--- a/src/storage/dd/DdMetaVariable.cpp
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -3,8 +3,12 @@
 namespace storm {
     namespace dd {
         template<DdType Type>
-        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), low(low), high(high), ddVariables(ddVariables), manager(manager) {
-            // Intentionally left empty.
+        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) noexcept : name(name), low(low), high(high), ddVariables(ddVariables), manager(manager) {
+            // Create the cube of all variables of this meta variable.
+            this->cube = this->getDdManager()->getOne();
+            for (auto const& ddVariable : this->ddVariables) {
+                this->cube *= ddVariable;
+            }
         }
         
         template<DdType Type>
@@ -21,6 +25,11 @@ namespace storm {
         int_fast64_t DdMetaVariable<Type>::getHigh() const {
             return this->high;
         }
+        
+        template<DdType Type>
+        std::shared_ptr<DdManager<Type>> DdMetaVariable<Type>::getDdManager() const {
+            return this->manager;
+        }
 
         template<DdType Type>
         std::vector<Dd<Type>> const& DdMetaVariable<Type>::getDdVariables() const {
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index 2631143f2..f784fda2c 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -14,8 +14,8 @@ namespace storm {
         
         template <DdType Type>
         class DdMetaVariable {
-            // Declare the other DD-related classes as friends so they can access the internals of a meta variable.
-            friend class Dd<Type>;
+            // Declare the DdManager class as friend so it can access the internals of a meta variable.
+            friend class DdManager<Type>;
             
             /*!
              * Creates a meta variable with the given name, range bounds.
@@ -26,7 +26,7 @@ namespace storm {
              * @param ddVariables The vector of variables used to encode this variable.
              * @param manager A pointer to the manager that is responsible for this meta variable.
              */
-            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
+            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) noexcept;
             
             // Explictly generate all default versions of copy/move constructors/assignments.
             DdMetaVariable(DdMetaVariable const& other) = default;
diff --git a/src/storage/dd/DdType.h b/src/storage/dd/DdType.h
new file mode 100644
index 000000000..327832ec5
--- /dev/null
+++ b/src/storage/dd/DdType.h
@@ -0,0 +1,12 @@
+#ifndef STORM_STORAGE_DD_DDTYPE_H_
+#define STORM_STORAGE_DD_DDTYPE_H_
+
+namespace storm {
+    namespace dd {
+        enum DdType {
+            CUDD
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_DDTYPE_H_ */

From 97e4e0125047740c334edea576e84fb82c445690 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 21 Mar 2014 19:08:26 +0100
Subject: [PATCH 027/147] Further step towards finalizing the abstraction layer
 for DDs.

Former-commit-id: efd5822b677716cfa87e19010c3198ea993e637b
---
 src/storage/dd/CuddDd.cpp         | 144 ++++++++++++++++++++++++++++--
 src/storage/dd/CuddDd.h           |  20 ++++-
 src/storage/dd/CuddDdManager.cpp  |   8 +-
 src/storage/dd/CuddDdManager.h    |   1 -
 src/storage/dd/DdMetaVariable.cpp |   1 +
 src/storage/dd/DdMetaVariable.h   |   5 +-
 6 files changed, 163 insertions(+), 16 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index d3ad10493..23f148da0 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -1,8 +1,9 @@
 #include "src/storage/dd/CuddDd.h"
+#include "src/storage/dd/CuddDdManager.h"
 
 namespace storm {
     namespace dd {
-        Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
+        Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
             // Intentionally left empty.
         }
         
@@ -13,10 +14,10 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator+=(Dd<CUDD> const& other) {
-            cuddAdd += other;
+            cuddAdd += other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
             
             return *this;
         }
@@ -28,10 +29,10 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator*=(Dd<CUDD> const& other) {
-            cuddAdd *= other;
+            cuddAdd *= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
             
             return *this;
         }
@@ -43,10 +44,10 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator-=(Dd<CUDD> const& other) {
-            cuddAdd -= other;
+            cuddAdd -= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
             
             return *this;
         }
@@ -58,10 +59,10 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
-            cuddAdd.Divide(other);
+            cuddAdd.Divide(other.getCuddAdd());
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
             
             return *this;
         }
@@ -77,12 +78,137 @@ namespace storm {
             return *this;
         }
         
+        Dd<CUDD> Dd<CUDD>::equals(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result.getCuddAdd().Equals(other.getCuddAdd());
+            return result;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::notEquals(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result.getCuddAdd().NotEquals(other.getCuddAdd());
+            return result;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::less(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result.getCuddAdd().LessThan(other.getCuddAdd());
+            return result;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::lessOrEqual(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result.getCuddAdd().LessThanOrEqual(other.getCuddAdd());
+            return result;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::greater(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result.getCuddAdd().GreaterThan(other.getCuddAdd());
+            return result;
+        }
+        
+        Dd<CUDD> Dd<CUDD>::greaterOrEqual(Dd<CUDD> const& other) const {
+            Dd<CUDD> result(*this);
+            result.getCuddAdd().GreaterThanOrEqual(other.getCuddAdd());
+            return result;
+        }
+        
+        void Dd<CUDD>::existsAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+            
+            for (auto const& metaVariableName : metaVariableNames) {
+                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                cubeDd *= metaVariable.getCube();
+            }
+            
+            this->getCuddAdd().OrAbstract(cubeDd.getCuddAdd());
+        }
+        
+        void Dd<CUDD>::sumAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+            
+            for (auto const& metaVariableName : metaVariableNames) {
+                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                cubeDd *= metaVariable.getCube();
+            }
+            
+            this->getCuddAdd().ExistAbstract(cubeDd.getCuddAdd());
+        }
+        
+        void Dd<CUDD>::minAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+            
+            for (auto const& metaVariableName : metaVariableNames) {
+                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                cubeDd *= metaVariable.getCube();
+            }
+            
+            this->getCuddAdd().Minimum(cubeDd.getCuddAdd());
+        }
+        
+        void Dd<CUDD>::maxAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+            
+            for (auto const& metaVariableName : metaVariableNames) {
+                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                cubeDd *= metaVariable.getCube();
+            }
+            
+            this->getCuddAdd().Maximum(cubeDd.getCuddAdd());
+        }
+        
+        void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
+            std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
+            metaVariableNameToValueMap.emplace(metaVariableName, variableValue);
+            this->setValue(metaVariableNameToValueMap, targetValue);
+        }
+        
+        void Dd<CUDD>::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) {
+            std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
+            metaVariableNameToValueMap.emplace(metaVariableName1, variableValue1);
+            metaVariableNameToValueMap.emplace(metaVariableName2, variableValue2);
+            this->setValue(metaVariableNameToValueMap, targetValue);
+        }
+        
+        void Dd<CUDD>::setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
+            // TODO: Fill this
+        }
+        
+        bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
+            auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
+            return metaVariable != containedMetaVariableNames.end();
+        }
+        
+        bool Dd<CUDD>::containsMetaVariables(std::unordered_set<std::string> metaVariableNames) const {
+            for (auto const& metaVariableName : metaVariableNames) {
+                auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
+                
+                if (metaVariable == containedMetaVariableNames.end()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        
+        std::unordered_set<std::string> const& Dd<CUDD>::getContainedMetaVariableNames() const {
+            return containedMetaVariableNames;
+        }
+        
         void Dd<CUDD>::exportToDot(std::string const& filename) const {
             FILE* filePointer = fopen(filename.c_str() , "w");
             this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer);
             fclose(filePointer);
         }
         
+        ADD Dd<CUDD>::getCuddAdd() {
+            return this->cuddAdd;
+        }
+        
+        ADD const& Dd<CUDD>::getCuddAdd() const {
+            return this->cuddAdd;
+        }
+        
         std::shared_ptr<DdManager<CUDD>> Dd<CUDD>::getDdManager() const {
             return this->ddManager;
         }
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index eff759bd3..b0a3e33eb 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -1,14 +1,18 @@
 #ifndef STORM_STORAGE_DD_CUDDDD_H_
 #define STORM_STORAGE_DD_CUDDDD_H_
 
+#include <unordered_set>
+#include <unordered_map>
+
 #include "src/storage/dd/Dd.h"
-#include "src/storage/dd/CuddDdManager.h"
 
 // Include the C++-interface of CUDD.
 #include "cuddObj.hh"
 
 namespace storm {
     namespace dd {
+        // Forward-declare the DdManager class.
+        template<DdType Type> class DdManager;
         
         template<>
         class Dd<CUDD> {
@@ -264,6 +268,20 @@ namespace storm {
             std::shared_ptr<DdManager<CUDD>> getDdManager() const;
             
         private:
+            /*!
+             * Retrieves the CUDD ADD object associated with this DD.
+             *
+             * @return The CUDD ADD object assoicated with this DD.
+             */
+            ADD getCuddAdd();
+            
+            /*!
+             * Retrieves the CUDD ADD object associated with this DD.
+             *
+             * @return The CUDD ADD object assoicated with this DD.
+             */
+            ADD const& getCuddAdd() const;
+            
             /*!
              * Creates a DD that encapsulates the given CUDD ADD.
              *
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 580c6c9a6..40c11fbaa 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -24,10 +24,10 @@ namespace storm {
             
             std::vector<Dd<CUDD>> variables;
             for (std::size_t i = 0; i < numberOfBits; ++i) {
-                variables.emplace_back(cuddManager.addVar());
+                variables.emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
             }
             
-            metaVariableMap.emplace(name, low, high, variables, this->shared_from_this());
+            metaVariableMap.emplace(name, DdMetaVariable<CUDD>(name, low, high, variables, this->shared_from_this()));
         }
         
         void DdManager<CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
@@ -40,13 +40,13 @@ namespace storm {
             std::vector<std::vector<Dd<CUDD>>> variables;
             for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
                 for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                    variables[i].emplace_back(cuddManager.addVar());
+                    variables[i].emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
                 }
             }
             
             // Now add the meta variables.
             for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                metaVariableMap.emplace(names[i], low, high, variables[i], this->shared_from_this());
+                metaVariableMap.emplace(names[i], DdMetaVariable<CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
             }
         }
         
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 72f2aea0c..ede42104d 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -16,7 +16,6 @@ namespace storm {
         template<>
         class DdManager<CUDD> : std::enable_shared_from_this<DdManager<CUDD>> {
             // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
-            friend class DdMetaVariable<CUDD>;
             friend class Dd<CUDD>;
 
             /*!
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
index c2795562b..d5cae858c 100644
--- a/src/storage/dd/DdMetaVariable.cpp
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -1,4 +1,5 @@
 #include "src/storage/dd/DdMetaVariable.h"
+#include "src/storage/dd/CuddDdManager.h"
 
 namespace storm {
     namespace dd {
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index f784fda2c..6bf5f6c3c 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -6,16 +6,19 @@
 #include <cstdint>
 #include <string>
 
-#include "src/storage/dd/CuddDdManager.h"
 #include "src/storage/dd/CuddDd.h"
 
 namespace storm {
     namespace dd {
+        // Forward-declare the DdManager class.
+        template<DdType Type> class DdManager;
         
         template <DdType Type>
         class DdMetaVariable {
+        public:
             // Declare the DdManager class as friend so it can access the internals of a meta variable.
             friend class DdManager<Type>;
+            friend class Dd<Type>;
             
             /*!
              * Creates a meta variable with the given name, range bounds.

From 874fc8a864876ec7456e294386c4ace06bf92217 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 23 Mar 2014 12:58:18 +0100
Subject: [PATCH 028/147] Alpha version of DD abstraction layer.

Former-commit-id: 98cc5f3aa7a6a836c86388e39a9af1579abbbf5a
---
 src/storage/dd/CuddDd.cpp         |  7 ++++++-
 src/storage/dd/CuddDd.h           |  3 ++-
 src/storage/dd/CuddDdManager.cpp  | 29 +++++++++++++++++++++++++++--
 src/storage/dd/CuddDdManager.h    | 14 +++++++++++++-
 src/storage/dd/DdMetaVariable.cpp | 10 +++++++---
 src/storage/dd/DdMetaVariable.h   |  7 +++++++
 6 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 23f148da0..648db72a4 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -172,7 +172,12 @@ namespace storm {
         }
         
         void Dd<CUDD>::setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
-            // TODO: Fill this
+            Dd<CUDD> valueEncoding(this->getDdManager()->getOne());
+            for (auto const& nameValuePair : metaVariableNameToValueMap) {
+                valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
+            }
+            
+            this->cuddAdd = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
         }
         
         bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index b0a3e33eb..215e7e6a7 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -19,8 +19,9 @@ namespace storm {
         public:
             // Declare the DdManager class as friend so it can access the internals of a DD.
             friend class DdManager<CUDD>;
-
+            
             // Instantiate all copy/move constructors/assignments with the default implementation.
+            Dd() = default;
             Dd(Dd<CUDD> const& other) = default;
             Dd(Dd<CUDD>&& other) = default;
             Dd& operator=(Dd<CUDD> const& other) = default;
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 40c11fbaa..cce1edbfe 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -18,9 +18,34 @@ namespace storm {
         Dd<CUDD> DdManager<CUDD>::getConstant(double value) {
             return Dd<CUDD>(this->shared_from_this(), cuddManager.constant(value), {""});
         }
+        
+        Dd<CUDD> DdManager<CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
+            std::vector<Dd<CUDD>> ddVariables = this->getMetaVariable(metaVariableName).getDdVariables();
+
+            Dd<CUDD> result;
+            if (value & (1ull << (ddVariables.size() - 1))) {
+                result = ddVariables[0];
+            } else {
+                result = ddVariables[0];
+            }
+            
+            for (std::size_t i = 1; i < ddVariables.size(); ++i) {
+                if (value & (1ull << (ddVariables.size() - i - 1))) {
+                    result *= ddVariables[i];
+                } else {
+                    result *= ~ddVariables[i];
+                }
+            }
+            
+            return result;
+        }
 
         void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
-            std::size_t numberOfBits = std::log2(high - low);
+            if (high == low) {
+                throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements.";
+            }
+            
+            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low)));
             
             std::vector<Dd<CUDD>> variables;
             for (std::size_t i = 0; i < numberOfBits; ++i) {
@@ -36,7 +61,7 @@ namespace storm {
             }
             
             // Add the variables in interleaved order.
-            std::size_t numberOfBits = std::log2(high - low);
+            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low)));
             std::vector<std::vector<Dd<CUDD>>> variables;
             for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
                 for (uint_fast64_t i = 0; i < names.size(); ++i) {
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index ede42104d..1d061b504 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -14,7 +14,8 @@
 namespace storm {
     namespace dd {
         template<>
-        class DdManager<CUDD> : std::enable_shared_from_this<DdManager<CUDD>> {
+        class DdManager<CUDD> : public std::enable_shared_from_this<DdManager<CUDD>> {
+        public:
             // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
             friend class Dd<CUDD>;
 
@@ -50,6 +51,17 @@ namespace storm {
              */
             Dd<CUDD> getConstant(double value);
 
+            /*!
+             * Retrieves the DD representing the function that maps all inputs which have the given meta variable equal
+             * to the given value one.
+             *
+             * @param metaVariableName The meta variable that is supposed to have the given value.
+             * @param value The value the meta variable is supposed to have.
+             * @return The DD representing the function that maps all inputs which have the given meta variable equal
+             * to the given value one.
+             */
+            Dd<CUDD> getEncoding(std::string const& metaVariableName, int_fast64_t value);
+            
             /*!
              * Adds a meta variable with the given name and range.
              *
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
index d5cae858c..72e7baba5 100644
--- a/src/storage/dd/DdMetaVariable.cpp
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -4,9 +4,8 @@
 namespace storm {
     namespace dd {
         template<DdType Type>
-        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) noexcept : name(name), low(low), high(high), ddVariables(ddVariables), manager(manager) {
+        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) noexcept : name(name), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
             // Create the cube of all variables of this meta variable.
-            this->cube = this->getDdManager()->getOne();
             for (auto const& ddVariable : this->ddVariables) {
                 this->cube *= ddVariable;
             }
@@ -27,6 +26,11 @@ namespace storm {
             return this->high;
         }
         
+        template<DdType Type>
+        std::size_t DdMetaVariable<Type>::getNumberOfDdVariables() const {
+            return this->ddVariables.size();
+        }
+        
         template<DdType Type>
         std::shared_ptr<DdManager<Type>> DdMetaVariable<Type>::getDdManager() const {
             return this->manager;
@@ -43,6 +47,6 @@ namespace storm {
         }
         
         // Explicitly instantiate DdMetaVariable.
-        template<> class DdMetaVariable<CUDD>;
+        template class DdMetaVariable<CUDD>;
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index 6bf5f6c3c..c5e7c00cf 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -65,6 +65,13 @@ namespace storm {
              */
             std::shared_ptr<DdManager<Type>> getDdManager() const;
             
+            
+            /*!
+             * Retrieves the number of DD variables for this meta variable.
+             *
+             * @return The number of DD variables for this meta variable.
+             */
+            std::size_t getNumberOfDdVariables() const;
         private:
             /*!
              * Retrieves the variables used to encode the meta variable.

From a63cda69f56f4586e5b7ec10ce3599d85a14042a Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 23 Mar 2014 13:09:36 +0100
Subject: [PATCH 029/147] Added function to retrieve range DD for meta
 variable.

Former-commit-id: 32ef6715f429172331027fd8b9919e0934a0fa1e
---
 src/storage/dd/CuddDdManager.cpp | 10 ++++++++++
 src/storage/dd/CuddDdManager.h   |  9 +++++++++
 2 files changed, 19 insertions(+)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index cce1edbfe..15f51a3b7 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -39,6 +39,16 @@ namespace storm {
             
             return result;
         }
+        
+        Dd<CUDD> DdManager<CUDD>::getRange(std::string const metaVariableName) {
+            storm::dd::DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
+            
+            Dd<CUDD> result = this->getZero();
+            for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
+                result.setValue(metaVariableName, value - metaVariable.getLow(), static_cast<double>(value));
+            }
+            return result;
+        }
 
         void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
             if (high == low) {
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 1d061b504..b826cce35 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -62,6 +62,15 @@ namespace storm {
              */
             Dd<CUDD> getEncoding(std::string const& metaVariableName, int_fast64_t value);
             
+            /*!
+             * Retrieves the DD representing the range of the meta variable, i.e., a function that maps all legal values
+             * of the range of the meta variable to one.
+             *
+             * @param metaVariableName The name of the meta variable whose range to retrieve.
+             * @return The range of the meta variable
+             */
+            Dd<CUDD> getRange(std::string const metaVariableName);
+            
             /*!
              * Adds a meta variable with the given name and range.
              *

From c2c353f6b9e929966ac4c86b6c758561900df05e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 23 Mar 2014 16:17:43 +0100
Subject: [PATCH 030/147] Readded missing file.

Former-commit-id: acc68213d496fce4c7332093e0c5f2a182c639bd
---
 CPackConfig.cmake | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 CPackConfig.cmake

diff --git a/CPackConfig.cmake b/CPackConfig.cmake
new file mode 100644
index 000000000..5ce6c0f53
--- /dev/null
+++ b/CPackConfig.cmake
@@ -0,0 +1,27 @@
+include(InstallRequiredSystemLibraries)
+
+# For help take a look at:
+# http://www.cmake.org/Wiki/CMake:CPackConfiguration
+
+### general settings
+set(CPACK_PACKAGE_NAME "StoRM")
+set(CPACK_PACKAGE_VENDOR "i2 RWTH Aachen University")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Stochastic Reward Model Checker - An extensible model checker written in C++.")
+
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
+
+### versions
+set(CPACK_PACKAGE_VERSION_MAJOR "${STORM_CPP_VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${STORM_CPP_VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${STORM_CPP_VERSION_PATCH}")
+set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${STORM_CPP_VERSION_HASH}")
+
+set(CPACK_GENERATOR "ZIP")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
+
+### source package settings
+set(CPACK_SOURCE_GENERATOR "ZIP")
+set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src")
+
+include(CPack)
\ No newline at end of file

From 52cd48c247d174febad28c979d99fb8127998efd Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 23 Mar 2014 17:19:39 +0100
Subject: [PATCH 031/147] Fixed bug in restriction of a program to certain
 commands. Also, modules may now have an action without actually having a
 command labeled with the action and the explicit model adapter now handles
 this correctly.

Former-commit-id: 6bbb4b807cbe6ed7f005a0b645c5a3b094854d20
---
 src/adapters/ExplicitModelAdapter.h |  7 +++++++
 src/ir/Module.cpp                   | 17 +++++++++++++++++
 src/ir/Module.h                     |  6 +-----
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index a2932b9c9..f1ef50396 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -233,6 +233,13 @@ namespace storm {
                     }
                     
                     std::set<uint_fast64_t> const& commandIndices = module.getCommandsByAction(action);
+                    
+                    // If the module contains the action, but there is no command in the module that is labeled with
+                    // this action, we don't have any feasible command combinations.
+                    if (commandIndices.empty()) {
+                        return boost::optional<std::vector<std::list<storm::ir::Command>>>();
+                    }
+                    
                     std::list<storm::ir::Command> commands;
                     
                     // Look up commands by their indices and add them if the guard evaluates to true in the given state.
diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp
index 6b67ee579..5724db8df 100644
--- a/src/ir/Module.cpp
+++ b/src/ir/Module.cpp
@@ -169,11 +169,16 @@ namespace storm {
             if (actionsCommandSetPair != this->actionsToCommandIndexMap.end()) {
                 return actionsCommandSetPair->second;
             }
+            
             LOG4CPLUS_ERROR(logger, "Action name '" << action << "' does not exist in module.");
             throw storm::exceptions::OutOfRangeException() << "Action name '" << action << "' does not exist in module.";
         }
         
         void Module::collectActions() {
+            // Clear the current mapping.
+            this->actionsToCommandIndexMap.clear();
+            
+            // Add the mapping for all commands.
             for (unsigned int id = 0; id < this->commands.size(); id++) {
                 std::string const& action = this->commands[id].getActionName();
                 if (action != "") {
@@ -184,9 +189,18 @@ namespace storm {
                     this->actions.insert(action);
                 }
             }
+            
+            // For all actions that are "in the module", but for which no command exists, we add the mapping to an empty
+            // set of commands.
+            for (auto const& action : this->actions) {
+                if (this->actionsToCommandIndexMap.find(action) == this->actionsToCommandIndexMap.end()) {
+                    this->actionsToCommandIndexMap[action] = std::set<uint_fast64_t>();
+                }
+            }
         }
         
         void Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
+            // First construct the new vector of commands.
             std::vector<storm::ir::Command> newCommands;
             for (auto const& command : commands) {
                 if (indexSet.find(command.getGlobalIndex()) != indexSet.end()) {
@@ -194,6 +208,9 @@ namespace storm {
                 }
             }
             commands = std::move(newCommands);
+            
+            // Then refresh the internal mappings.
+            this->collectActions();
         }
         
     } // namespace ir
diff --git a/src/ir/Module.h b/src/ir/Module.h
index e6762bb8d..d9570c652 100644
--- a/src/ir/Module.h
+++ b/src/ir/Module.h
@@ -188,8 +188,8 @@ namespace storm {
              * @param indexSet The set of indices for which to keep the commands.
              */
             void restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
-        private:
             
+        private:
             /*!
              * Computes the locally maintained mappings for fast data retrieval.
              */
@@ -217,11 +217,7 @@ namespace storm {
             std::set<std::string> actions;
             
             // A map of actions to the set of commands labeled with this action.
-#ifdef LINUX
-            boost::container::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
-#else
             std::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
-#endif
         };
         
     } // namespace ir

From dea56e1bd407984b00b63ef974744e47c7af37e0 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 24 Mar 2014 00:08:23 +0100
Subject: [PATCH 032/147] Added some missing includes and some stubs for
 additional functionality of DD abstraction layer.

Former-commit-id: d90d525993228f8d5255c6cbd1950e6f781e4f10
---
 src/storage/dd/CuddDd.cpp        | 80 +++++++++++++++++++++++++++++---
 src/storage/dd/CuddDd.h          | 57 +++++++++++++++++++++++
 src/storage/dd/CuddDdManager.cpp |  2 +
 3 files changed, 132 insertions(+), 7 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 648db72a4..2b1648a8c 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -1,12 +1,18 @@
 #include "src/storage/dd/CuddDd.h"
 #include "src/storage/dd/CuddDdManager.h"
 
+#include "src/exceptions/InvalidArgumentException.h"
+
 namespace storm {
     namespace dd {
         Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
             // Intentionally left empty.
         }
         
+        bool Dd<CUDD>::operator==(Dd<CUDD> const& other) const {
+            return this->getCuddAdd() == other.getCuddAdd();
+        }
+        
         Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
             result += other;
@@ -14,7 +20,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator+=(Dd<CUDD> const& other) {
-            cuddAdd += other.getCuddAdd();
+            this->getCuddAdd() += other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
             std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
@@ -29,7 +35,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator*=(Dd<CUDD> const& other) {
-            cuddAdd *= other.getCuddAdd();
+            this->getCuddAdd() *= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
             std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
@@ -44,7 +50,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator-=(Dd<CUDD> const& other) {
-            cuddAdd -= other.getCuddAdd();
+            this->getCuddAdd() -= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
             std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
@@ -59,7 +65,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
-            cuddAdd.Divide(other.getCuddAdd());
+            this->getCuddAdd().Divide(other.getCuddAdd());
             
             // Join the variable sets of the two participating DDs.
             std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
@@ -74,7 +80,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::complement() {
-            cuddAdd = ~cuddAdd;
+            this->getCuddAdd() = ~this->getCuddAdd();
             return *this;
         }
         
@@ -118,6 +124,12 @@ namespace storm {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
+                // First check whether the DD contains the meta variable and erase it, if this is the case.
+                if (!this->containsMetaVariable(metaVariableName)) {
+                    throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
+                }
+                this->getContainedMetaVariableNames().erase(metaVariableName);
+                
                 DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
@@ -129,6 +141,12 @@ namespace storm {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
+                // First check whether the DD contains the meta variable and erase it, if this is the case.
+                if (!this->containsMetaVariable(metaVariableName)) {
+                    throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
+                }
+                this->getContainedMetaVariableNames().erase(metaVariableName);
+                
                 DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
@@ -140,6 +158,12 @@ namespace storm {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
+                // First check whether the DD contains the meta variable and erase it, if this is the case.
+                if (!this->containsMetaVariable(metaVariableName)) {
+                    throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
+                }
+                this->getContainedMetaVariableNames().erase(metaVariableName);
+                
                 DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
@@ -151,6 +175,12 @@ namespace storm {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
+                // First check whether the DD contains the meta variable and erase it, if this is the case.
+                if (!this->containsMetaVariable(metaVariableName)) {
+                    throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
+                }
+                this->getContainedMetaVariableNames().erase(metaVariableName);
+                
                 DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
@@ -158,6 +188,30 @@ namespace storm {
             this->getCuddAdd().Maximum(cubeDd.getCuddAdd());
         }
         
+        uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
+            std::size_t numberOfDdVariables = 0;
+            for (auto const& metaVariableName : this->containedMetaVariableNames) {
+                numberOfDdVariables += this->getDdManager()->getMetaVariable(metaVariableName).getNumberOfDdVariables();
+            }
+            return static_cast<uint_fast64_t>(this->cuddAdd.CountMinterm(static_cast<int>(numberOfDdVariables)));
+        }
+        
+        uint_fast64_t Dd<CUDD>::getLeafCount() const {
+            return static_cast<uint_fast64_t>(this->cuddAdd.CountLeaves());
+        }
+        
+        double Dd<CUDD>::getMin() const {
+            ADD constantMinAdd = this->getCuddAdd().FindMin();
+            // FIXME
+            return 0;
+        }
+        
+        double Dd<CUDD>::getMax() const {
+            ADD constantMaxAdd = this->getCuddAdd().FindMax();
+            // FIXME
+            return 0;
+        }
+        
         void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
             std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
             metaVariableNameToValueMap.emplace(metaVariableName, variableValue);
@@ -177,7 +231,15 @@ namespace storm {
                 valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
             }
             
-            this->cuddAdd = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
+            this->getCuddAdd() = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
+        }
+        
+        bool Dd<CUDD>::isOne() const {
+            return *this == this->getDdManager()->getOne();
+        }
+        
+        bool Dd<CUDD>::isZero() const {
+            return *this == this->getDdManager()->getZero();
         }
         
         bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
@@ -197,7 +259,11 @@ namespace storm {
         }
         
         std::unordered_set<std::string> const& Dd<CUDD>::getContainedMetaVariableNames() const {
-            return containedMetaVariableNames;
+            return this->containedMetaVariableNames;
+        }
+        
+        std::unordered_set<std::string>& Dd<CUDD>::getContainedMetaVariableNames() {
+            return this->containedMetaVariableNames;
         }
         
         void Dd<CUDD>::exportToDot(std::string const& filename) const {
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 215e7e6a7..ffb82f400 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -3,6 +3,7 @@
 
 #include <unordered_set>
 #include <unordered_map>
+#include <memory>
 
 #include "src/storage/dd/Dd.h"
 
@@ -27,6 +28,13 @@ namespace storm {
             Dd& operator=(Dd<CUDD> const& other) = default;
             Dd& operator=(Dd<CUDD>&& other) = default;
             
+            /*!
+             * Retrieves whether the two DDs represent the same function.
+             *
+             * @param other The DD that is to be compared with the current one.
+             */
+            bool operator==(Dd<CUDD> const& other) const;
+            
             /*!
              * Adds the two DDs.
              *
@@ -194,6 +202,34 @@ namespace storm {
              */
             void maxAbstract(std::unordered_set<std::string> const& metaVariableNames);
 
+            /*!
+             * Retrieves the number of encodings that are mapped to a non-zero value.
+             *
+             * @return The number of encodings that are mapped to a non-zero value.
+             */
+            uint_fast64_t getNonZeroCount() const;
+            
+            /*!
+             * Retrieves the number of leaves of the DD.
+             *
+             * @return The number of leaves of the DD.
+             */
+            uint_fast64_t getLeafCount() const;
+            
+            /*!
+             * Retrieves the lowest function value of any encoding.
+             *
+             * @return The lowest function value of any encoding.
+             */
+            double getMin() const;
+            
+            /*!
+             * Retrieves the highest function value of any encoding.
+             *
+             * @return The highest function value of any encoding.
+             */
+            double getMax() const;
+            
             /*!
              * Sets the function values of all encodings that have the given value of the meta variable to the given
              * target value.
@@ -231,6 +267,20 @@ namespace storm {
              */
             void setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
             
+            /*!
+             * Retrieves whether this DD represents the constant one function.
+             *
+             * @return True if this DD represents the constant one function.
+             */
+            bool isOne() const;
+            
+            /*!
+             * Retrieves whether this DD represents the constant zero function.
+             *
+             * @return True if this DD represents the constant zero function.
+             */
+            bool isZero() const;
+            
             /*!
              * Retrieves whether the given meta variable is contained in the DD.
              *
@@ -254,6 +304,13 @@ namespace storm {
              */
             std::unordered_set<std::string> const& getContainedMetaVariableNames() const;
             
+            /*!
+             * Retrieves the set of all names of meta variables contained in the DD.
+             *
+             * @return The set of names of all meta variables contained in the DD.
+             */
+            std::unordered_set<std::string>& getContainedMetaVariableNames();
+            
             /*!
              * Exports the DD to the given file in the dot format.
              *
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 15f51a3b7..1c691522d 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -1,3 +1,5 @@
+#include <cmath>
+
 #include "src/storage/dd/CuddDdManager.h"
 #include "src/exceptions/InvalidArgumentException.h"
 

From 4252a2710c44f159aaa4b460464e5daa767f18ff Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 24 Mar 2014 14:19:06 +0100
Subject: [PATCH 033/147] Renamed CPackConfig.cmake to StormCPackConfig.cmake
 and adapted reference in CMakeLists.txt accordingly. Also, CPackConfig.cmake
 is now ignored.

Former-commit-id: d24d731950d8c307dcec44ee1c6e2e0614f24f70
---
 .gitignore                                  | 1 +
 CMakeLists.txt                              | 2 +-
 CPackConfig.cmake => StormCPackConfig.cmake | 0
 3 files changed, 2 insertions(+), 1 deletion(-)
 rename CPackConfig.cmake => StormCPackConfig.cmake (100%)

diff --git a/.gitignore b/.gitignore
index 8d18b13b4..aa15c7b9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,7 @@ resources/3rdparty/cudd-2.5.0/
 ipch/
 obj/
 CMakeFiles/
+CPackConfig.cmake
 # The build Dir
 build/
 build//CMakeLists.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8942c984f..5831d731f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -519,4 +519,4 @@ INSTALL(TARGETS storm storm-functional-tests storm-performance-tests
 	LIBRARY DESTINATION lib
 	ARCHIVE DESTINATION lib
 )
-include(CPackConfig.cmake)
\ No newline at end of file
+include(StormCPackConfig.cmake)
\ No newline at end of file
diff --git a/CPackConfig.cmake b/StormCPackConfig.cmake
similarity index 100%
rename from CPackConfig.cmake
rename to StormCPackConfig.cmake

From ac355a66eb55869675d19eaa057c4b88e10d39f5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 24 Mar 2014 16:04:40 +0100
Subject: [PATCH 034/147] Further work on DD layer.

Former-commit-id: 061b428763617ec66c61eed91f0a9f7dd1d9bc56
---
 src/storage/dd/CuddDd.cpp | 45 +++++++++++++++++++++++++++++++++++----
 src/storage/dd/CuddDd.h   | 29 +++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 2b1648a8c..6276a422b 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -188,6 +188,33 @@ namespace storm {
             this->getCuddAdd().Maximum(cubeDd.getCuddAdd());
         }
         
+        void Dd<CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
+            std::vector<ADD> from;
+            std::vector<ADD> to;
+            for (auto const& metaVariablePair : metaVariablePairs) {
+                DdMetaVariable<CUDD> const& variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first);
+                DdMetaVariable<CUDD> const& variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second);
+
+                // Check if it's legal so swap the meta variables.
+                if (variable1.getNumberOfDdVariables() != variable2.getNumberOfDdVariables()) {
+                    throw storm::exceptions::InvalidArgumentException() << "Unable to swap meta variables with different size.";
+                }
+                
+                // Keep track of the contained meta variables in the DD.
+                bool containsVariable1 = this->containsMetaVariable(metaVariablePair.first);
+                bool containsVariable2 = this->containsMetaVariable(metaVariablePair.second);
+                if (containsVariable1 && !containsVariable2) {
+                    this->removeContainedMetaVariable(metaVariablePair.first);
+                    this->addContainedMetaVariable(metaVariablePair.second);
+                } else if (!containsVariable1 && containsVariable2) {
+                    this->removeContainedMetaVariable(metaVariablePair.second);
+                    this->addContainedMetaVariable(metaVariablePair.first);
+                }
+            }
+            
+            // FIXME: complete this and add matrix-matrix multiplication.
+        }
+        
         uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
             for (auto const& metaVariableName : this->containedMetaVariableNames) {
@@ -200,16 +227,18 @@ namespace storm {
             return static_cast<uint_fast64_t>(this->cuddAdd.CountLeaves());
         }
         
+        uint_fast64_t Dd<CUDD>::getNodeCount() const {
+            return static_cast<uint_fast64_t>(this->cuddAdd.nodeCount());
+        }
+        
         double Dd<CUDD>::getMin() const {
             ADD constantMinAdd = this->getCuddAdd().FindMin();
-            // FIXME
-            return 0;
+            return static_cast<double>(Cudd_V(constantMinAdd));
         }
         
         double Dd<CUDD>::getMax() const {
             ADD constantMaxAdd = this->getCuddAdd().FindMax();
-            // FIXME
-            return 0;
+            return static_cast<double>(Cudd_V(constantMaxAdd));
         }
         
         void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
@@ -280,6 +309,14 @@ namespace storm {
             return this->cuddAdd;
         }
         
+        void Dd<CUDD>::addContainedMetaVariable(std::string const& metaVariableName) {
+            this->getContainedMetaVariableNames().insert(metaVariableName);
+        }
+
+        void Dd<CUDD>::removeContainedMetaVariable(std::string const& metaVariableName) {
+            this->getContainedMetaVariableNames().erase(metaVariableName);
+        }
+        
         std::shared_ptr<DdManager<CUDD>> Dd<CUDD>::getDdManager() const {
             return this->ddManager;
         }
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index ffb82f400..a07db98d6 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -202,6 +202,14 @@ namespace storm {
              */
             void maxAbstract(std::unordered_set<std::string> const& metaVariableNames);
 
+            /*!
+             * Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
+             * the same number of underlying DD variables.
+             *
+             * @param metaVariablePairs A vector of meta variable pairs that are to be swapped for one another.
+             */
+            void swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs);
+            
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.
              *
@@ -216,6 +224,13 @@ namespace storm {
              */
             uint_fast64_t getLeafCount() const;
             
+            /*!
+             * Retrieves the number of nodes necessary to represent the DD.
+             *
+             * @return The number of nodes in this DD.
+             */
+            uint_fast64_t getNodeCount() const;
+            
             /*!
              * Retrieves the lowest function value of any encoding.
              *
@@ -340,6 +355,20 @@ namespace storm {
              */
             ADD const& getCuddAdd() const;
             
+            /*!
+             * Adds the given meta variable name to the set of meta variables that are contained in this DD.
+             *
+             * @param metaVariableName The name of the meta variable to add.
+             */
+            void addContainedMetaVariable(std::string const& metaVariableName);
+            
+            /*!
+             * Removes the given meta variable name to the set of meta variables that are contained in this DD.
+             *
+             * @param metaVariableName The name of the meta variable to remove.
+             */
+            void removeContainedMetaVariable(std::string const& metaVariableName);
+
             /*!
              * Creates a DD that encapsulates the given CUDD ADD.
              *

From cb35b3315daad61e20ddff3f7aa89104e210787c Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 24 Mar 2014 22:32:51 +0100
Subject: [PATCH 035/147] Added matrix-matrix multiplication to DD interface.
 (This includes matrix-vector multiplication as a special case).

Former-commit-id: d5d8fef7386f39402514540143f19b73a147ae68
---
 src/storage/dd/CuddDd.cpp        | 54 ++++++++++++++++++++++++--------
 src/storage/dd/CuddDd.h          | 31 ++++++++++++------
 src/storage/dd/CuddDdManager.cpp |  4 +--
 src/storage/dd/CuddDdManager.h   |  3 +-
 4 files changed, 65 insertions(+), 27 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 6276a422b..be51d5a98 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace dd {
-        Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
+        Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
             // Intentionally left empty.
         }
         
@@ -23,7 +23,7 @@ namespace storm {
             this->getCuddAdd() += other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
             
             return *this;
         }
@@ -38,7 +38,7 @@ namespace storm {
             this->getCuddAdd() *= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
             
             return *this;
         }
@@ -53,7 +53,7 @@ namespace storm {
             this->getCuddAdd() -= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
             
             return *this;
         }
@@ -68,7 +68,7 @@ namespace storm {
             this->getCuddAdd().Divide(other.getCuddAdd());
             
             // Join the variable sets of the two participating DDs.
-            std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end()));
+            this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
             
             return *this;
         }
@@ -120,7 +120,7 @@ namespace storm {
             return result;
         }
         
-        void Dd<CUDD>::existsAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+        void Dd<CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
@@ -137,7 +137,7 @@ namespace storm {
             this->getCuddAdd().OrAbstract(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::sumAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+        void Dd<CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
@@ -154,7 +154,7 @@ namespace storm {
             this->getCuddAdd().ExistAbstract(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::minAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+        void Dd<CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
@@ -171,7 +171,7 @@ namespace storm {
             this->getCuddAdd().Minimum(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::maxAbstract(std::unordered_set<std::string> const& metaVariableNames) {
+        void Dd<CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
             Dd<CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
@@ -210,11 +210,39 @@ namespace storm {
                     this->removeContainedMetaVariable(metaVariablePair.second);
                     this->addContainedMetaVariable(metaVariablePair.first);
                 }
+                
+                // Add the variables to swap to the corresponding vectors.
+                for (auto const& ddVariable : variable1.getDdVariables()) {
+                    from.push_back(ddVariable.getCuddAdd());
+                }
+                for (auto const& ddVariable : variable2.getDdVariables()) {
+                    to.push_back(ddVariable.getCuddAdd());
+                }
             }
             
-            // FIXME: complete this and add matrix-matrix multiplication.
+            // Finally, call CUDD to swap the variables.
+            this->getCuddAdd().SwapVariables(from, to);
         }
         
+        Dd<CUDD> Dd<CUDD>::multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
+            std::vector<ADD> summationDdVariables;
+            
+            // Create the CUDD summation variables.
+            for (auto const& metaVariableName : summationMetaVariableNames) {
+                for (auto const& ddVariable : this->getDdManager()->getMetaVariable(metaVariableName).getDdVariables()) {
+                    summationDdVariables.push_back(ddVariable.getCuddAdd());
+                }
+            }
+            
+            std::set<std::string> unionOfMetaVariableNames;
+            std::set_union(this->getContainedMetaVariableNames().begin(), this->getContainedMetaVariableNames().end(), otherMatrix.getContainedMetaVariableNames().begin(), otherMatrix.getContainedMetaVariableNames().end(), std::inserter(unionOfMetaVariableNames, unionOfMetaVariableNames.begin()));
+            std::set<std::string> containedMetaVariableNames;
+            std::set_difference(unionOfMetaVariableNames.begin(), unionOfMetaVariableNames.end(), summationMetaVariableNames.begin(), summationMetaVariableNames.end(), std::inserter(containedMetaVariableNames, containedMetaVariableNames.begin()));
+            
+            return Dd<CUDD>(this->getDdManager(), this->getCuddAdd().MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
+        }
+
+        
         uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
             for (auto const& metaVariableName : this->containedMetaVariableNames) {
@@ -276,7 +304,7 @@ namespace storm {
             return metaVariable != containedMetaVariableNames.end();
         }
         
-        bool Dd<CUDD>::containsMetaVariables(std::unordered_set<std::string> metaVariableNames) const {
+        bool Dd<CUDD>::containsMetaVariables(std::set<std::string> metaVariableNames) const {
             for (auto const& metaVariableName : metaVariableNames) {
                 auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
                 
@@ -287,11 +315,11 @@ namespace storm {
             return true;
         }
         
-        std::unordered_set<std::string> const& Dd<CUDD>::getContainedMetaVariableNames() const {
+        std::set<std::string> const& Dd<CUDD>::getContainedMetaVariableNames() const {
             return this->containedMetaVariableNames;
         }
         
-        std::unordered_set<std::string>& Dd<CUDD>::getContainedMetaVariableNames() {
+        std::set<std::string>& Dd<CUDD>::getContainedMetaVariableNames() {
             return this->containedMetaVariableNames;
         }
         
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index a07db98d6..0aa71889e 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -1,8 +1,8 @@
 #ifndef STORM_STORAGE_DD_CUDDDD_H_
 #define STORM_STORAGE_DD_CUDDDD_H_
 
-#include <unordered_set>
 #include <unordered_map>
+#include <set>
 #include <memory>
 
 #include "src/storage/dd/Dd.h"
@@ -179,28 +179,28 @@ namespace storm {
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void existsAbstract(std::unordered_set<std::string> const& metaVariableNames);
+            void existsAbstract(std::set<std::string> const& metaVariableNames);
 
             /*!
              * Sum-abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void sumAbstract(std::unordered_set<std::string> const& metaVariableNames);
+            void sumAbstract(std::set<std::string> const& metaVariableNames);
             
             /*!
              * Min-abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void minAbstract(std::unordered_set<std::string> const& metaVariableNames);
+            void minAbstract(std::set<std::string> const& metaVariableNames);
             
             /*!
              * Max-abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void maxAbstract(std::unordered_set<std::string> const& metaVariableNames);
+            void maxAbstract(std::set<std::string> const& metaVariableNames);
 
             /*!
              * Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
@@ -210,6 +210,17 @@ namespace storm {
              */
             void swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs);
             
+            /*!
+             * Multiplies the current DD (representing a matrix) with the given matrix by summing over the given meta
+             * variables.
+             *
+             * @param otherMatrix The matrix with which to multiply.
+             * @param summationMetaVariableNames The names of the meta variables over which to sum during the matrix-
+             * matrix multiplication.
+             * @return A DD representing the result of the matrix-matrix multiplication.
+             */
+            Dd<CUDD> multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames);
+            
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.
              *
@@ -310,21 +321,21 @@ namespace storm {
              * @param metaVariableNames The names of the meta variable for which to query membership.
              * @return True iff all meta variables are contained in the DD.
              */
-            bool containsMetaVariables(std::unordered_set<std::string> metaVariableNames) const;
+            bool containsMetaVariables(std::set<std::string> metaVariableNames) const;
             
             /*!
              * Retrieves the set of all names of meta variables contained in the DD.
              *
              * @return The set of names of all meta variables contained in the DD.
              */
-            std::unordered_set<std::string> const& getContainedMetaVariableNames() const;
+            std::set<std::string> const& getContainedMetaVariableNames() const;
             
             /*!
              * Retrieves the set of all names of meta variables contained in the DD.
              *
              * @return The set of names of all meta variables contained in the DD.
              */
-            std::unordered_set<std::string>& getContainedMetaVariableNames();
+            std::set<std::string>& getContainedMetaVariableNames();
             
             /*!
              * Exports the DD to the given file in the dot format.
@@ -376,7 +387,7 @@ namespace storm {
              * @param cuddAdd The CUDD ADD to store.
              * @param
              */
-            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::unordered_set<std::string> const& containedMetaVariableNames) noexcept;
+            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) noexcept;
             
             // A pointer to the manager responsible for this DD.
             std::shared_ptr<DdManager<CUDD>> ddManager;
@@ -385,7 +396,7 @@ namespace storm {
             ADD cuddAdd;
             
             // The names of all meta variables that appear in this DD.
-            std::unordered_set<std::string> containedMetaVariableNames;
+            std::set<std::string> containedMetaVariableNames;
         };
     }
 }
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 1c691522d..e6ca9e8e7 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -97,8 +97,8 @@ namespace storm {
             return nameVariablePair->second;
         }
         
-        std::unordered_set<std::string> DdManager<CUDD>::getAllMetaVariableNames() const {
-            std::unordered_set<std::string> result;
+        std::set<std::string> DdManager<CUDD>::getAllMetaVariableNames() const {
+            std::set<std::string> result;
             for (auto const& nameValuePair : metaVariableMap) {
                 result.insert(nameValuePair.first);
             }
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index b826cce35..76da42bd5 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -1,7 +1,6 @@
 #ifndef STORM_STORAGE_DD_CUDDDDMANAGER_H_
 #define STORM_STORAGE_DD_CUDDDDMANAGER_H_
 
-#include <unordered_set>
 #include <unordered_map>
 
 #include "src/storage/dd/DdManager.h"
@@ -102,7 +101,7 @@ namespace storm {
              *
              * @return The set of all meta variable names of the manager.
              */
-            std::unordered_set<std::string> getAllMetaVariableNames() const;
+            std::set<std::string> getAllMetaVariableNames() const;
             
         private:
             /*!

From d6ff967ef04a898476c7864cba562bec7777325e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 27 Mar 2014 10:20:02 +0100
Subject: [PATCH 036/147] Added missing algorithm header inclusion.

Former-commit-id: 32231ecb8d0e8927cbde64c33b8a1cc667b855eb
---
 src/storage/dd/CuddDd.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index be51d5a98..23db4562d 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -1,3 +1,5 @@
+#include <algorithm>
+
 #include "src/storage/dd/CuddDd.h"
 #include "src/storage/dd/CuddDdManager.h"
 

From 386fac39358c28a0848c6162aa995ae7af5d768b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 27 Mar 2014 10:37:26 +0100
Subject: [PATCH 037/147] Removed faulty deletion of cudd utility (is obsolete
 now anyway).

Former-commit-id: c4dca6c50fa8762fc53ad24fbc2b2c62ff5eafda
---
 src/storm.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/storm.cpp b/src/storm.cpp
index ef23b9f2f..81e77cf11 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -240,7 +240,7 @@ void setUp() {
  * Performs some necessary clean-up.
  */
 void cleanUp() {
-	delete storm::utility::cuddUtilityInstance();
+    // Intentionally left empty.
 }
 
 /*!

From 7ea7ce93e22852a5593c38bd9bee8d3f14d78535 Mon Sep 17 00:00:00 2001
From: dbohlender <dimitri.bohlender@rwth-aachen.de>
Date: Thu, 27 Mar 2014 10:58:41 +0100
Subject: [PATCH 038/147] Fixed MSVC incompabilities

Former-commit-id: 67749daab8f6873c66d6b45048db02ebfc8c5f0f
---
 src/storage/dd/CuddDd.cpp         |  4 +++-
 src/storage/dd/CuddDd.h           | 11 +++++++----
 src/storage/dd/CuddDdManager.cpp  |  2 +-
 src/storage/dd/CuddDdManager.h    | 13 +++++++++----
 src/storage/dd/DdMetaVariable.cpp |  2 +-
 src/storage/dd/DdMetaVariable.h   | 13 +++++++++----
 6 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index be51d5a98..873107d27 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -1,3 +1,5 @@
+#include <algorithm>
+
 #include "src/storage/dd/CuddDd.h"
 #include "src/storage/dd/CuddDdManager.h"
 
@@ -5,7 +7,7 @@
 
 namespace storm {
     namespace dd {
-        Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
+        Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
             // Intentionally left empty.
         }
         
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 0aa71889e..74a1a6c7f 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -6,6 +6,7 @@
 #include <memory>
 
 #include "src/storage/dd/Dd.h"
+#include "utility\OsDetection.h"
 
 // Include the C++-interface of CUDD.
 #include "cuddObj.hh"
@@ -24,9 +25,11 @@ namespace storm {
             // Instantiate all copy/move constructors/assignments with the default implementation.
             Dd() = default;
             Dd(Dd<CUDD> const& other) = default;
-            Dd(Dd<CUDD>&& other) = default;
-            Dd& operator=(Dd<CUDD> const& other) = default;
-            Dd& operator=(Dd<CUDD>&& other) = default;
+			Dd& operator=(Dd<CUDD> const& other) = default;
+			#ifndef WINDOWS
+				Dd(Dd<CUDD>&& other) = default;
+				Dd& operator=(Dd<CUDD>&& other) = default;
+			#endif
             
             /*!
              * Retrieves whether the two DDs represent the same function.
@@ -387,7 +390,7 @@ namespace storm {
              * @param cuddAdd The CUDD ADD to store.
              * @param
              */
-            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) noexcept;
+            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames);
             
             // A pointer to the manager responsible for this DD.
             std::shared_ptr<DdManager<CUDD>> ddManager;
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index e6ca9e8e7..931b968d9 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace dd {
-        DdManager<CUDD>::DdManager() noexcept : metaVariableMap(), cuddManager() {
+        DdManager<CUDD>::DdManager() : metaVariableMap(), cuddManager() {
             // Intentionally left empty.
         }
         
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 76da42bd5..25feb01cf 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -6,6 +6,7 @@
 #include "src/storage/dd/DdManager.h"
 #include "src/storage/dd/DdMetaVariable.h"
 #include "src/storage/dd/CuddDd.h"
+#include "utility\OsDetection.h"
 
 // Include the C++-interface of CUDD.
 #include "cuddObj.hh"
@@ -21,13 +22,17 @@ namespace storm {
             /*!
              * Creates an empty manager without any meta variables.
              */
-            DdManager() noexcept;
+            DdManager();
             
             // Explictly forbid copying a DdManager, but allow moving it.
             DdManager(DdManager<CUDD> const& other) = delete;
-            DdManager(DdManager<CUDD>&& other) = default;
-            DdManager<CUDD>& operator=(DdManager<CUDD> const& other) = delete;
-            DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
+			DdManager<CUDD>& operator=(DdManager<CUDD> const& other) = delete;
+			#ifndef WINDOWS
+				DdManager(DdManager<CUDD>&& other) = default;
+				DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
+			#endif
+            
+            
             
             /*!
              * Retrieves a DD representing the constant one function.
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
index 72e7baba5..7671289fc 100644
--- a/src/storage/dd/DdMetaVariable.cpp
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -4,7 +4,7 @@
 namespace storm {
     namespace dd {
         template<DdType Type>
-        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) noexcept : name(name), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
+        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
             // Create the cube of all variables of this meta variable.
             for (auto const& ddVariable : this->ddVariables) {
                 this->cube *= ddVariable;
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index c5e7c00cf..2212cf265 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -6,6 +6,7 @@
 #include <cstdint>
 #include <string>
 
+#include "utility\OsDetection.h"
 #include "src/storage/dd/CuddDd.h"
 
 namespace storm {
@@ -29,13 +30,17 @@ namespace storm {
              * @param ddVariables The vector of variables used to encode this variable.
              * @param manager A pointer to the manager that is responsible for this meta variable.
              */
-            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) noexcept;
+            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
             
             // Explictly generate all default versions of copy/move constructors/assignments.
             DdMetaVariable(DdMetaVariable const& other) = default;
-            DdMetaVariable(DdMetaVariable&& other) = default;
-            DdMetaVariable& operator=(DdMetaVariable const& other) = default;
-            DdMetaVariable& operator=(DdMetaVariable&& other) = default;
+			DdMetaVariable& operator=(DdMetaVariable const& other) = default;
+			#ifndef WINDOWS
+				DdMetaVariable(DdMetaVariable&& other) = default;
+				DdMetaVariable& operator=(DdMetaVariable&& other) = default;
+			#endif
+            
+            
             
             /*!
              * Retrieves the name of the meta variable.

From dd15e6019383e0ca54137628f29d08690e0efa79 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 27 Mar 2014 10:37:26 +0100
Subject: [PATCH 039/147] Removed faulty deletion of cudd utility (is obsolete
 now anyway).

Former-commit-id: 743c59ceca680284a4bb6a23aac1a7e3081d6d31
---
 src/storm.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/storm.cpp b/src/storm.cpp
index ef23b9f2f..81e77cf11 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -240,7 +240,7 @@ void setUp() {
  * Performs some necessary clean-up.
  */
 void cleanUp() {
-	delete storm::utility::cuddUtilityInstance();
+    // Intentionally left empty.
 }
 
 /*!

From 2fcb12e8752c5348e1042e5099e0a86341da13a7 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 28 Mar 2014 11:18:15 +0100
Subject: [PATCH 040/147] Fixed some backslashes in includes to slashes and
 changed indentation of some code.

Former-commit-id: 0e4828e3685debe90a095d9a6f82298988f7fc87
---
 src/storage/dd/CuddDd.h         | 24 ++++++++++++------------
 src/storage/dd/CuddDdManager.h  | 16 +++++++---------
 src/storage/dd/DdMetaVariable.h | 18 ++++++++----------
 3 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 74a1a6c7f..414190b2e 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -6,7 +6,7 @@
 #include <memory>
 
 #include "src/storage/dd/Dd.h"
-#include "utility\OsDetection.h"
+#include "src/utility/OsDetection.h"
 
 // Include the C++-interface of CUDD.
 #include "cuddObj.hh"
@@ -26,10 +26,10 @@ namespace storm {
             Dd() = default;
             Dd(Dd<CUDD> const& other) = default;
 			Dd& operator=(Dd<CUDD> const& other) = default;
-			#ifndef WINDOWS
-				Dd(Dd<CUDD>&& other) = default;
-				Dd& operator=(Dd<CUDD>&& other) = default;
-			#endif
+#ifndef WINDOWS
+            Dd(Dd<CUDD>&& other) = default;
+            Dd& operator=(Dd<CUDD>&& other) = default;
+#endif
             
             /*!
              * Retrieves whether the two DDs represent the same function.
@@ -45,7 +45,7 @@ namespace storm {
              * @return The result of the addition.
              */
             Dd<CUDD> operator+(Dd<CUDD> const& other) const;
-
+            
             /*!
              * Adds the given DD to the current one.
              *
@@ -61,7 +61,7 @@ namespace storm {
              * @return The result of the multiplication.
              */
             Dd<CUDD> operator*(Dd<CUDD> const& other) const;
-
+            
             /*!
              * Multiplies the given DD with the current one and assigns the result to the current DD.
              *
@@ -183,7 +183,7 @@ namespace storm {
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
             void existsAbstract(std::set<std::string> const& metaVariableNames);
-
+            
             /*!
              * Sum-abstracts from the given meta variables.
              *
@@ -204,7 +204,7 @@ namespace storm {
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
             void maxAbstract(std::set<std::string> const& metaVariableNames);
-
+            
             /*!
              * Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
              * the same number of underlying DD variables.
@@ -269,7 +269,7 @@ namespace storm {
              * @param targetValue The new function value of the modified encodings.
              */
             void setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue);
-
+            
             /*!
              * Sets the function values of all encodings that have the given values of the two meta variables to the
              * given target value.
@@ -382,7 +382,7 @@ namespace storm {
              * @param metaVariableName The name of the meta variable to remove.
              */
             void removeContainedMetaVariable(std::string const& metaVariableName);
-
+            
             /*!
              * Creates a DD that encapsulates the given CUDD ADD.
              *
@@ -394,7 +394,7 @@ namespace storm {
             
             // A pointer to the manager responsible for this DD.
             std::shared_ptr<DdManager<CUDD>> ddManager;
-
+            
             // The ADD created by CUDD.
             ADD cuddAdd;
             
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 25feb01cf..666376719 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -6,7 +6,7 @@
 #include "src/storage/dd/DdManager.h"
 #include "src/storage/dd/DdMetaVariable.h"
 #include "src/storage/dd/CuddDd.h"
-#include "utility\OsDetection.h"
+#include "src/utility/OsDetection.h"
 
 // Include the C++-interface of CUDD.
 #include "cuddObj.hh"
@@ -18,7 +18,7 @@ namespace storm {
         public:
             // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
             friend class Dd<CUDD>;
-
+            
             /*!
              * Creates an empty manager without any meta variables.
              */
@@ -27,12 +27,10 @@ namespace storm {
             // Explictly forbid copying a DdManager, but allow moving it.
             DdManager(DdManager<CUDD> const& other) = delete;
 			DdManager<CUDD>& operator=(DdManager<CUDD> const& other) = delete;
-			#ifndef WINDOWS
-				DdManager(DdManager<CUDD>&& other) = default;
-				DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
-			#endif
-            
-            
+#ifndef WINDOWS
+            DdManager(DdManager<CUDD>&& other) = default;
+            DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
+#endif
             
             /*!
              * Retrieves a DD representing the constant one function.
@@ -54,7 +52,7 @@ namespace storm {
              * @return A DD representing the constant function with the given value.
              */
             Dd<CUDD> getConstant(double value);
-
+            
             /*!
              * Retrieves the DD representing the function that maps all inputs which have the given meta variable equal
              * to the given value one.
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index 2212cf265..994b0841a 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -6,7 +6,7 @@
 #include <cstdint>
 #include <string>
 
-#include "utility\OsDetection.h"
+#include "utility/OsDetection.h"
 #include "src/storage/dd/CuddDd.h"
 
 namespace storm {
@@ -35,12 +35,10 @@ namespace storm {
             // Explictly generate all default versions of copy/move constructors/assignments.
             DdMetaVariable(DdMetaVariable const& other) = default;
 			DdMetaVariable& operator=(DdMetaVariable const& other) = default;
-			#ifndef WINDOWS
-				DdMetaVariable(DdMetaVariable&& other) = default;
-				DdMetaVariable& operator=(DdMetaVariable&& other) = default;
-			#endif
-            
-            
+#ifndef WINDOWS
+            DdMetaVariable(DdMetaVariable&& other) = default;
+            DdMetaVariable& operator=(DdMetaVariable&& other) = default;
+#endif
             
             /*!
              * Retrieves the name of the meta variable.
@@ -55,14 +53,14 @@ namespace storm {
              * @return The lowest value of the range of the variable.
              */
             int_fast64_t getLow() const;
-
+            
             /*!
              * Retrieves the highest value of the range of the variable.
              *
              * @return The highest value of the range of the variable.
              */
             int_fast64_t getHigh() const;
-
+            
             /*!
              * Retrieves the manager that is responsible for this meta variable.
              *
@@ -91,7 +89,7 @@ namespace storm {
              * @return The cube of all variables that encode this meta variable.
              */
             Dd<Type> const& getCube() const;
-
+            
             // The name of the meta variable.
             std::string name;
             

From a4fec9f080320283ee130ff08d8bee0e7b8016ec Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 28 Mar 2014 15:13:38 +0100
Subject: [PATCH 041/147] Started writing functional tests for DD abstraction
 layer and fixed some bugs on the way.

Former-commit-id: 8a2fc118bea53c4f82c1228402971b19631fee2b
---
 src/storage/dd/CuddDd.cpp              |  4 +-
 src/storage/dd/CuddDd.h                |  2 +-
 src/storage/dd/CuddDdManager.cpp       | 47 +++++++++++++++++++---
 src/storage/dd/CuddDdManager.h         | 15 +++++++
 test/functional/storage/CuddDdTest.cpp | 54 ++++++++++++++++++++++++++
 5 files changed, 114 insertions(+), 8 deletions(-)
 create mode 100644 test/functional/storage/CuddDdTest.cpp

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 873107d27..eba51a557 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -263,12 +263,12 @@ namespace storm {
         
         double Dd<CUDD>::getMin() const {
             ADD constantMinAdd = this->getCuddAdd().FindMin();
-            return static_cast<double>(Cudd_V(constantMinAdd));
+            return static_cast<double>(Cudd_V(constantMinAdd.getNode()));
         }
         
         double Dd<CUDD>::getMax() const {
             ADD constantMaxAdd = this->getCuddAdd().FindMax();
-            return static_cast<double>(Cudd_V(constantMaxAdd));
+            return static_cast<double>(Cudd_V(constantMaxAdd.getNode()));
         }
         
         void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 414190b2e..1f8339fe6 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -390,7 +390,7 @@ namespace storm {
              * @param cuddAdd The CUDD ADD to store.
              * @param
              */
-            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames);
+            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
             
             // A pointer to the manager responsible for this DD.
             std::shared_ptr<DdManager<CUDD>> ddManager;
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 931b968d9..d8a7096a0 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -1,8 +1,11 @@
 #include <cmath>
+#include <algorithm>
 
 #include "src/storage/dd/CuddDdManager.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
+#include <iostream>
+
 namespace storm {
     namespace dd {
         DdManager<CUDD>::DdManager() : metaVariableMap(), cuddManager() {
@@ -10,15 +13,15 @@ namespace storm {
         }
         
         Dd<CUDD> DdManager<CUDD>::getOne() {
-            return Dd<CUDD>(this->shared_from_this(), cuddManager.addOne(), {""});
+            return Dd<CUDD>(this->shared_from_this(), cuddManager.addOne());
         }
         
         Dd<CUDD> DdManager<CUDD>::getZero() {
-            return Dd<CUDD>(this->shared_from_this(), cuddManager.addZero(), {""});
+            return Dd<CUDD>(this->shared_from_this(), cuddManager.addZero());
         }
         
         Dd<CUDD> DdManager<CUDD>::getConstant(double value) {
-            return Dd<CUDD>(this->shared_from_this(), cuddManager.constant(value), {""});
+            return Dd<CUDD>(this->shared_from_this(), cuddManager.constant(value));
         }
         
         Dd<CUDD> DdManager<CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
@@ -53,6 +56,12 @@ namespace storm {
         }
 
         void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
+            // Check whether a meta variable already exists.
+            if (this->containsMetaVariable(name)) {
+                throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
+            }
+
+            // Check that the range is legal.
             if (high == low) {
                 throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements.";
             }
@@ -68,13 +77,33 @@ namespace storm {
         }
         
         void DdManager<CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
+            // Make sure that at least one meta variable is added.
             if (names.size() == 0) {
                 throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables.";
             }
             
+            // Check that there are no duplicate names in the given name vector.
+            std::vector<std::string> nameCopy(names);
+            std::sort(nameCopy.begin(), nameCopy.end());
+            if (std::adjacent_find(nameCopy.begin(), nameCopy.end()) != nameCopy.end()) {
+                throw storm::exceptions::InvalidArgumentException() << "Cannot add duplicate meta variables.";
+            }
+            
+            // Check that the range is legal.
+            if (high == low) {
+                throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements.";
+            }
+
+            // Check whether a meta variable already exists.
+            for (auto const& metaVariableName : names) {
+                if (this->containsMetaVariable(metaVariableName)) {
+                    throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << metaVariableName << "' already exists.";
+                }
+            }
+            
             // Add the variables in interleaved order.
             std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low)));
-            std::vector<std::vector<Dd<CUDD>>> variables;
+            std::vector<std::vector<Dd<CUDD>>> variables(names.size());
             for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
                 for (uint_fast64_t i = 0; i < names.size(); ++i) {
                     variables[i].emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
@@ -90,7 +119,7 @@ namespace storm {
         DdMetaVariable<CUDD> const& DdManager<CUDD>::getMetaVariable(std::string const& metaVariableName) const {
             auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
             
-            if (nameVariablePair == metaVariableMap.end()) {
+            if (!this->containsMetaVariable(metaVariableName)) {
                 throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name.";
             }
             
@@ -105,6 +134,14 @@ namespace storm {
             return result;
         }
         
+        std::size_t DdManager<CUDD>::getNumberOfMetaVariables() const {
+            return this->metaVariableMap.size();
+        }
+        
+        bool DdManager<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
+            return this->metaVariableMap.find(metaVariableName) != this->metaVariableMap.end();
+        }
+        
         Cudd& DdManager<CUDD>::getCuddManager() {
             return this->cuddManager;
         }
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 666376719..4e421f9ec 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -106,6 +106,21 @@ namespace storm {
              */
             std::set<std::string> getAllMetaVariableNames() const;
             
+            /*!
+             * Retrieves the number of meta variables that are contained in this manager.
+             *
+             * @return The number of meta variables contained in this manager.
+             */
+            std::size_t getNumberOfMetaVariables() const;
+            
+            /*!
+             * Retrieves whether the given meta variable name is already in use.
+             *
+             * @param metaVariableName The meta variable name whose membership to query.
+             * @return True if the given meta variable name is managed by this manager.
+             */
+            bool containsMetaVariable(std::string const& metaVariableName) const;
+            
         private:
             /*!
              * Retrieves the underlying CUDD manager.
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
new file mode 100644
index 000000000..3a9b1dde9
--- /dev/null
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -0,0 +1,54 @@
+#include "gtest/gtest.h"
+#include "storm-config.h"
+#include "src/exceptions/InvalidArgumentException.h"
+#include "src/storage/dd/CuddDdManager.h"
+#include "src/storage/dd/CuddDd.h"
+#include "src/storage/dd/DdMetaVariable.h"
+
+TEST(CuddDdManager, Constants) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    storm::dd::Dd<storm::dd::CUDD> zero;
+    ASSERT_NO_THROW(zero = manager->getZero());
+    
+    EXPECT_EQ(0, zero.getNonZeroCount());
+    EXPECT_EQ(1, zero.getLeafCount());
+    EXPECT_EQ(1, zero.getNodeCount());
+    EXPECT_EQ(0, zero.getMin());
+    EXPECT_EQ(0, zero.getMax());
+    
+    storm::dd::Dd<storm::dd::CUDD> one;
+    ASSERT_NO_THROW(one = manager->getOne());
+    
+    EXPECT_EQ(1, one.getNonZeroCount());
+    EXPECT_EQ(1, one.getLeafCount());
+    EXPECT_EQ(1, one.getNodeCount());
+    EXPECT_EQ(1, one.getMin());
+    EXPECT_EQ(1, one.getMax());
+
+    storm::dd::Dd<storm::dd::CUDD> two;
+    ASSERT_NO_THROW(two = manager->getConstant(2));
+    
+    EXPECT_EQ(1, two.getNonZeroCount());
+    EXPECT_EQ(1, two.getLeafCount());
+    EXPECT_EQ(1, two.getNodeCount());
+    EXPECT_EQ(2, two.getMin());
+    EXPECT_EQ(2, two.getMax());
+}
+
+TEST(CuddDdManager, AddMetaVariableTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    EXPECT_EQ(1, manager->getNumberOfMetaVariables());
+    
+    std::vector<std::string> names = {"x", "x'"};
+    ASSERT_THROW(manager->addMetaVariablesInterleaved(names, 0, 3), storm::exceptions::InvalidArgumentException);
+
+    names = {"y", "y"};
+    ASSERT_THROW(manager->addMetaVariablesInterleaved(names, 0, 3), storm::exceptions::InvalidArgumentException);
+    
+    names = {"y", "y'"};
+    ASSERT_NO_THROW(manager->addMetaVariablesInterleaved(names, 0, 3));
+    EXPECT_EQ(3, manager->getNumberOfMetaVariables());
+}
\ No newline at end of file

From 6b07643c9623599800f45a90e528df85380ef0ca Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 28 Mar 2014 16:57:55 +0100
Subject: [PATCH 042/147] Further tests for DD layer and bugfixing.

Former-commit-id: 752a8c55ac6b506af523927c135343be9ab2b2c1
---
 src/storage/dd/CuddDdManager.cpp       | 12 ++++++------
 src/storage/dd/CuddDdManager.h         |  2 +-
 src/storage/dd/DdMetaVariable.h        |  2 +-
 test/functional/storage/CuddDdTest.cpp | 21 +++++++++++++++++++--
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index d8a7096a0..dd6ce4f4f 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -57,7 +57,7 @@ namespace storm {
 
         void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
             // Check whether a meta variable already exists.
-            if (this->containsMetaVariable(name)) {
+            if (this->hasMetaVariable(name)) {
                 throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
             }
 
@@ -66,7 +66,7 @@ namespace storm {
                 throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements.";
             }
             
-            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low)));
+            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
             
             std::vector<Dd<CUDD>> variables;
             for (std::size_t i = 0; i < numberOfBits; ++i) {
@@ -96,13 +96,13 @@ namespace storm {
 
             // Check whether a meta variable already exists.
             for (auto const& metaVariableName : names) {
-                if (this->containsMetaVariable(metaVariableName)) {
+                if (this->hasMetaVariable(metaVariableName)) {
                     throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << metaVariableName << "' already exists.";
                 }
             }
             
             // Add the variables in interleaved order.
-            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low)));
+            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
             std::vector<std::vector<Dd<CUDD>>> variables(names.size());
             for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
                 for (uint_fast64_t i = 0; i < names.size(); ++i) {
@@ -119,7 +119,7 @@ namespace storm {
         DdMetaVariable<CUDD> const& DdManager<CUDD>::getMetaVariable(std::string const& metaVariableName) const {
             auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
             
-            if (!this->containsMetaVariable(metaVariableName)) {
+            if (!this->hasMetaVariable(metaVariableName)) {
                 throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name.";
             }
             
@@ -138,7 +138,7 @@ namespace storm {
             return this->metaVariableMap.size();
         }
         
-        bool DdManager<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
+        bool DdManager<CUDD>::hasMetaVariable(std::string const& metaVariableName) const {
             return this->metaVariableMap.find(metaVariableName) != this->metaVariableMap.end();
         }
         
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 4e421f9ec..1d0d32a99 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -119,7 +119,7 @@ namespace storm {
              * @param metaVariableName The meta variable name whose membership to query.
              * @return True if the given meta variable name is managed by this manager.
              */
-            bool containsMetaVariable(std::string const& metaVariableName) const;
+            bool hasMetaVariable(std::string const& metaVariableName) const;
             
         private:
             /*!
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index 994b0841a..f6c90cc21 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -68,13 +68,13 @@ namespace storm {
              */
             std::shared_ptr<DdManager<Type>> getDdManager() const;
             
-            
             /*!
              * Retrieves the number of DD variables for this meta variable.
              *
              * @return The number of DD variables for this meta variable.
              */
             std::size_t getNumberOfDdVariables() const;
+            
         private:
             /*!
              * Retrieves the variables used to encode the meta variable.
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 3a9b1dde9..a92dbc929 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -36,7 +36,7 @@ TEST(CuddDdManager, Constants) {
     EXPECT_EQ(2, two.getMax());
 }
 
-TEST(CuddDdManager, AddMetaVariableTest) {
+TEST(CuddDdManager, MetaVariableTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
     
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
@@ -51,4 +51,21 @@ TEST(CuddDdManager, AddMetaVariableTest) {
     names = {"y", "y'"};
     ASSERT_NO_THROW(manager->addMetaVariablesInterleaved(names, 0, 3));
     EXPECT_EQ(3, manager->getNumberOfMetaVariables());
-}
\ No newline at end of file
+    
+    EXPECT_FALSE(manager->hasMetaVariable("x'"));
+    EXPECT_TRUE(manager->hasMetaVariable("y'"));
+    
+    std::set<std::string> metaVariableSet = {"x", "y", "y'"};
+    EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames());
+    
+    ASSERT_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x'"), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
+    storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x");
+    
+    EXPECT_EQ(1, metaVariableX.getLow());
+    EXPECT_EQ(9, metaVariableX.getHigh());
+    EXPECT_EQ("x", metaVariableX.getName());
+    EXPECT_EQ(manager, metaVariableX.getDdManager());
+    EXPECT_EQ(4, metaVariableX.getNumberOfDdVariables());
+}
+

From a528610d985d015f9f0307bc12bd39de17d1c0df Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Sat, 29 Mar 2014 15:04:32 +0100
Subject: [PATCH 043/147] version is now written into a seperate header file to
 prevent recompile of many files after a commit

Former-commit-id: a287aacefa12dbab2516037840b10849fadda34e
---
 CMakeLists.txt     |  7 +++++++
 src/storm.cpp      |  1 +
 storm-config.h.in  |  7 -------
 storm-version.h.in | 12 ++++++++++++
 4 files changed, 20 insertions(+), 7 deletions(-)
 create mode 100644 storm-version.h.in

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5831d731f..09eef57a9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -216,6 +216,13 @@ configure_file (
 	"${PROJECT_SOURCE_DIR}/storm-config.h.in"
 	"${PROJECT_BINARY_DIR}/include/storm-config.h"
 )
+
+# Configure a header file to pass the storm version to the source code
+configure_file (
+	"${PROJECT_SOURCE_DIR}/storm-version.h.in"
+	"${PROJECT_BINARY_DIR}/include/storm-version.h"
+)
+
 # Add the binary dir include directory for storm-config.h
 include_directories("${PROJECT_BINARY_DIR}/include")
 
diff --git a/src/storm.cpp b/src/storm.cpp
index 81e77cf11..a13bf8e23 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include "storm-config.h"
+#include "storm-version.h"
 #include "src/models/Dtmc.h"
 #include "src/models/MarkovAutomaton.h"
 #include "src/storage/SparseMatrix.h"
diff --git a/storm-config.h.in b/storm-config.h.in
index 85a33e032..cb90e5af6 100644
--- a/storm-config.h.in
+++ b/storm-config.h.in
@@ -8,13 +8,6 @@
 #ifndef STORM_GENERATED_STORMCONFIG_H_
 #define STORM_GENERATED_STORMCONFIG_H_
  
-// Version Information
-#define STORM_CPP_VERSION_MAJOR @STORM_CPP_VERSION_MAJOR@					// The major version of StoRM
-#define STORM_CPP_VERSION_MINOR @STORM_CPP_VERSION_MINOR@					// The minor version of StoRM
-#define STORM_CPP_VERSION_PATCH @STORM_CPP_VERSION_PATCH@					// The patch version of StoRM
-#define STORM_CPP_VERSION_COMMITS_AHEAD @STORM_CPP_VERSION_COMMITS_AHEAD@ 	// How many commits passed since the tag was last set
-#define STORM_CPP_VERSION_HASH "@STORM_CPP_VERSION_HASH@" 					// The short hash of the git commit this build is bases on
-#define STORM_CPP_VERSION_DIRTY @STORM_CPP_VERSION_DIRTY@ 					// 0 iff there no files were modified in the checkout, 1 else
 
 // The path of the sources from which StoRM will be/was build
 #define STORM_CPP_BASE_PATH "@PROJECT_SOURCE_DIR@"
diff --git a/storm-version.h.in b/storm-version.h.in
new file mode 100644
index 000000000..5ccac6125
--- /dev/null
+++ b/storm-version.h.in
@@ -0,0 +1,12 @@
+#ifndef STORM_GENERATED_VERSION_H_
+#define STORM_GENERATED_VERSION_H_
+
+// Version Information
+#define STORM_CPP_VERSION_MAJOR @STORM_CPP_VERSION_MAJOR@					// The major version of StoRM
+#define STORM_CPP_VERSION_MINOR @STORM_CPP_VERSION_MINOR@					// The minor version of StoRM
+#define STORM_CPP_VERSION_PATCH @STORM_CPP_VERSION_PATCH@					// The patch version of StoRM
+#define STORM_CPP_VERSION_COMMITS_AHEAD @STORM_CPP_VERSION_COMMITS_AHEAD@ 	// How many commits passed since the tag was last set
+#define STORM_CPP_VERSION_HASH "@STORM_CPP_VERSION_HASH@" 					// The short hash of the git commit this build is bases on
+#define STORM_CPP_VERSION_DIRTY @STORM_CPP_VERSION_DIRTY@ 					// 0 iff there no files were modified in the checkout, 1 else
+
+#endif
\ No newline at end of file

From 0eb13c6415a7101b8f5527ce5d9699028537a182 Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Sat, 29 Mar 2014 15:20:42 +0100
Subject: [PATCH 044/147] fixed a lot of unused variable warnings

Former-commit-id: 806f74b30d501e2f463d99ea58f8b6a2d66a83ef
---
 src/adapters/SymbolicModelAdapter.h                       | 2 --
 src/counterexamples/MILPMinimalLabelSetGenerator.h        | 8 --------
 src/models/MarkovAutomaton.h                              | 2 +-
 src/solver/GlpkLpSolver.cpp                               | 2 --
 src/solver/GmmxxLinearEquationSolver.cpp                  | 1 -
 src/solver/GmmxxNondeterministicLinearEquationSolver.cpp  | 1 -
 src/solver/NativeLinearEquationSolver.cpp                 | 1 -
 src/solver/NativeNondeterministicLinearEquationSolver.cpp | 1 -
 src/storage/BitVector.cpp                                 | 2 --
 src/storage/SparseMatrix.cpp                              | 1 -
 src/utility/vector.h                                      | 1 -
 11 files changed, 1 insertion(+), 21 deletions(-)

diff --git a/src/adapters/SymbolicModelAdapter.h b/src/adapters/SymbolicModelAdapter.h
index be0729729..29ab6c613 100644
--- a/src/adapters/SymbolicModelAdapter.h
+++ b/src/adapters/SymbolicModelAdapter.h
@@ -157,7 +157,6 @@ private:
 
 			for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) {
 				storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j);
-				bool initialValue = booleanVariable.getInitialValue()->getValueAsBool(nullptr);
 				*initialStates *= *cuddUtility->getConstantEncoding(1, variableToRowDecisionDiagramVariableMap[booleanVariable.getName()]);
 			}
 			for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) {
@@ -187,7 +186,6 @@ private:
 		}
 
 		bool changed;
-		int iter = 0;
 		do {
 			changed = false;
 			*newReachableStates = *reachableStates * *systemAdd01;
diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index 027369182..de9c6b057 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -169,7 +169,6 @@ namespace storm {
              * @return A mapping from labels to variable indices.
              */
             static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createLabelVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
                 for (auto const& label : relevantLabels) {
@@ -190,7 +189,6 @@ namespace storm {
              * @return A mapping from states to a list of choice variable indices.
              */
             static std::pair<std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>>, uint_fast64_t> createSchedulerVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
                 std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> resultingMap;
@@ -219,7 +217,6 @@ namespace storm {
              * @return A mapping from initial states to choice variable indices.
              */
             static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
                 std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
@@ -245,7 +242,6 @@ namespace storm {
              * @return A mapping from states to the index of the corresponding probability variables.
              */
             static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createProbabilityVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
                 std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
@@ -269,7 +265,6 @@ namespace storm {
              * @return The index of the variable for the probability of the virtual initial state.
              */
             static std::pair<uint_fast64_t, uint_fast64_t> createVirtualInitialStateVariable(storm::solver::LpSolver& solver, bool maximizeProbability = false) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 variableNameBuffer << "pinit";
                 
@@ -285,7 +280,6 @@ namespace storm {
              * @return A mapping from problematic states to the index of the corresponding variables.
              */
             static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
                 std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
@@ -329,7 +323,6 @@ namespace storm {
              * @return A mapping from problematic choices to the index of the corresponding variables.
              */
             static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
-                int error = 0;
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
                 std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash> resultingMap;
@@ -539,7 +532,6 @@ namespace storm {
              */
             static uint_fast64_t assertReachabilityProbabilities(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
                 uint_fast64_t numberOfConstraintsCreated = 0;
-                int error = 0;
                 for (auto state : stateInformation.relevantStates) {
                     std::vector<double> coefficients;
                     std::vector<uint_fast64_t> variables;
diff --git a/src/models/MarkovAutomaton.h b/src/models/MarkovAutomaton.h
index 1f9250c10..22b6ab13f 100644
--- a/src/models/MarkovAutomaton.h
+++ b/src/models/MarkovAutomaton.h
@@ -123,7 +123,7 @@ namespace storm {
                     }
                     
                     // Then compute how many rows the new matrix is going to have.
-                    uint_fast64_t newNumberOfRows = this->getNumberOfChoices() - numberOfHybridStates;
+                    //uint_fast64_t newNumberOfRows = this->getNumberOfChoices() - numberOfHybridStates;
                     
                     // Create the matrix for the new transition relation and the corresponding nondeterministic choice vector.
                     storm::storage::SparseMatrixBuilder<T> newTransitionMatrixBuilder(0, 0, 0, true, this->getNumberOfStates() + 1);
diff --git a/src/solver/GlpkLpSolver.cpp b/src/solver/GlpkLpSolver.cpp
index e343526f2..e122fcb16 100644
--- a/src/solver/GlpkLpSolver.cpp
+++ b/src/solver/GlpkLpSolver.cpp
@@ -110,8 +110,6 @@ namespace storm {
             glp_set_row_name(this->lp, nextConstraintIndex, name.c_str());
             
             // Determine the type of the constraint and add it properly.
-            bool isUpperBound = boundType == LESS || boundType == LESS_EQUAL;
-            bool isStrict = boundType == LESS || boundType == GREATER;
             switch (boundType) {
                 case LESS:
                     glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightHandSideValue - storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
diff --git a/src/solver/GmmxxLinearEquationSolver.cpp b/src/solver/GmmxxLinearEquationSolver.cpp
index f81f4267a..c7ef52247 100644
--- a/src/solver/GmmxxLinearEquationSolver.cpp
+++ b/src/solver/GmmxxLinearEquationSolver.cpp
@@ -152,7 +152,6 @@ namespace storm {
 
             // Set up some temporary variables so that we can just swap pointers instead of copying the result after
             // each iteration.
-            std::vector<ValueType>* swap = nullptr;
             std::vector<ValueType>* currentX = &x;
 
             bool multiplyResultProvided = true;
diff --git a/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp b/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp
index 29829f535..1b408d740 100644
--- a/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp
+++ b/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp
@@ -59,7 +59,6 @@ namespace storm {
                 newX = new std::vector<ValueType>(x.size());
                 xMemoryProvided = false;
             }
-            std::vector<ValueType>* swap = nullptr;
             uint_fast64_t iterations = 0;
             bool converged = false;
             
diff --git a/src/solver/NativeLinearEquationSolver.cpp b/src/solver/NativeLinearEquationSolver.cpp
index d55b4e2e5..d26ad0344 100644
--- a/src/solver/NativeLinearEquationSolver.cpp
+++ b/src/solver/NativeLinearEquationSolver.cpp
@@ -106,7 +106,6 @@ namespace storm {
         void NativeLinearEquationSolver<ValueType>::performMatrixVectorMultiplication(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n, std::vector<ValueType>* multiplyResult) const {
             // Set up some temporary variables so that we can just swap pointers instead of copying the result after
             // each iteration.
-            std::vector<ValueType>* swap = nullptr;
             std::vector<ValueType>* currentX = &x;
             
             bool multiplyResultProvided = true;
diff --git a/src/solver/NativeNondeterministicLinearEquationSolver.cpp b/src/solver/NativeNondeterministicLinearEquationSolver.cpp
index 5dc25f2c1..7f88258f1 100644
--- a/src/solver/NativeNondeterministicLinearEquationSolver.cpp
+++ b/src/solver/NativeNondeterministicLinearEquationSolver.cpp
@@ -54,7 +54,6 @@ namespace storm {
                 newX = new std::vector<ValueType>(x.size());
                 xMemoryProvided = false;
             }
-            std::vector<ValueType>* swap = nullptr;
             uint_fast64_t iterations = 0;
             bool converged = false;
 
diff --git a/src/storage/BitVector.cpp b/src/storage/BitVector.cpp
index b4b282e0b..6907c45be 100644
--- a/src/storage/BitVector.cpp
+++ b/src/storage/BitVector.cpp
@@ -200,7 +200,6 @@ namespace storm {
         }
         
         BitVector& BitVector::operator&=(BitVector const& other) {
-            uint_fast64_t minSize =	std::min(other.bucketVector.size(), bucketVector.size());
             
             std::vector<uint64_t>::iterator it = bucketVector.begin();
             for (std::vector<uint64_t>::const_iterator otherIt = other.bucketVector.begin(); it != bucketVector.end() && otherIt != other.bucketVector.end(); ++it, ++otherIt) {
@@ -224,7 +223,6 @@ namespace storm {
         }
         
         BitVector& BitVector::operator|=(BitVector const& other) {
-            uint_fast64_t minSize =	std::min(other.bucketVector.size(), bucketVector.size());
             
             std::vector<uint64_t>::iterator it = bucketVector.begin();
             for (std::vector<uint64_t>::const_iterator otherIt = other.bucketVector.begin(); it != bucketVector.end() && otherIt != other.bucketVector.end(); ++it, ++otherIt) {
diff --git a/src/storage/SparseMatrix.cpp b/src/storage/SparseMatrix.cpp
index 0f8d0acfa..6955ec053 100644
--- a/src/storage/SparseMatrix.cpp
+++ b/src/storage/SparseMatrix.cpp
@@ -743,7 +743,6 @@ namespace storm {
             const_iterator it = this->begin();
             const_iterator ite;
             typename std::vector<uint_fast64_t>::const_iterator rowIterator = rowIndications.begin();
-            typename std::vector<uint_fast64_t>::const_iterator rowIteratorEnd = rowIndications.end();
             typename std::vector<T>::iterator resultIterator = result.begin();
             typename std::vector<T>::iterator resultIteratorEnd = result.end();
             
diff --git a/src/utility/vector.h b/src/utility/vector.h
index dd3bb2a1f..82913a902 100644
--- a/src/utility/vector.h
+++ b/src/utility/vector.h
@@ -94,7 +94,6 @@ namespace storm {
              */
             template<class T>
             void selectVectorValues(std::vector<T>& vector, std::vector<uint_fast64_t> const& rowGroupToRowIndexMapping, std::vector<uint_fast64_t> const& rowGrouping, std::vector<T> const& values) {
-                uint_fast64_t oldPosition = 0;
                 for (uint_fast64_t i = 0; i < vector.size(); ++i) {
                     vector[i] = values[rowGrouping[i] + rowGroupToRowIndexMapping[i]];
                 }

From cf5c04065eec918b2cfa1b2d5442236801ed5c82 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 28 Mar 2014 19:24:24 +0100
Subject: [PATCH 045/147] Added streaming functionality to DD. More tests, more
 bugfixes.

Former-commit-id: 3c3078fbdcd9414ab52894c26a36806730f75a4f
---
 src/storage/dd/CuddDd.cpp              | 18 ++++++++++---
 src/storage/dd/CuddDd.h                | 10 +++++---
 src/storage/dd/CuddDdManager.cpp       | 16 +++++++++---
 test/functional/storage/CuddDdTest.cpp | 35 +++++++++++++++++++++++++-
 4 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index eba51a557..aa3b7c675 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -326,12 +326,16 @@ namespace storm {
         }
         
         void Dd<CUDD>::exportToDot(std::string const& filename) const {
-            FILE* filePointer = fopen(filename.c_str() , "w");
-            this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer);
-            fclose(filePointer);
+            if (filename.empty()) {
+                this->getDdManager()->getCuddManager().DumpDot({this->getCuddAdd()});
+            } else {
+                FILE* filePointer = fopen(filename.c_str() , "w");
+                this->getDdManager()->getCuddManager().DumpDot({this->getCuddAdd()}, nullptr, nullptr, filePointer);
+                fclose(filePointer);
+            }
         }
         
-        ADD Dd<CUDD>::getCuddAdd() {
+        ADD& Dd<CUDD>::getCuddAdd() {
             return this->cuddAdd;
         }
         
@@ -350,5 +354,11 @@ namespace storm {
         std::shared_ptr<DdManager<CUDD>> Dd<CUDD>::getDdManager() const {
             return this->ddManager;
         }
+        
+        std::ostream & operator<<(std::ostream& out, const Dd<CUDD>& dd) {
+            dd.exportToDot();
+            return out;
+        }
+
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 1f8339fe6..0255ae58e 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -4,6 +4,7 @@
 #include <unordered_map>
 #include <set>
 #include <memory>
+#include <iostream>
 
 #include "src/storage/dd/Dd.h"
 #include "src/utility/OsDetection.h"
@@ -345,7 +346,7 @@ namespace storm {
              *
              * @param filename The name of the file to which the DD is to be exported.
              */
-            void exportToDot(std::string const& filename) const;
+            void exportToDot(std::string const& filename = "") const;
             
             /*!
              * Retrieves the manager that is responsible for this DD.
@@ -354,13 +355,14 @@ namespace storm {
              */
             std::shared_ptr<DdManager<CUDD>> getDdManager() const;
             
+            friend std::ostream & operator<<(std::ostream& out, const Dd<CUDD>& dd);
         private:
             /*!
-             * Retrieves the CUDD ADD object associated with this DD.
+             * Retrieves a reference to the CUDD ADD object associated with this DD.
              *
-             * @return The CUDD ADD object assoicated with this DD.
+             * @return The CUDD ADD object associated with this DD.
              */
-            ADD getCuddAdd();
+            ADD& getCuddAdd();
             
             /*!
              * Retrieves the CUDD ADD object associated with this DD.
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index dd6ce4f4f..4b96e685a 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -4,8 +4,6 @@
 #include "src/storage/dd/CuddDdManager.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
-#include <iostream>
-
 namespace storm {
     namespace dd {
         DdManager<CUDD>::DdManager() : metaVariableMap(), cuddManager() {
@@ -25,7 +23,17 @@ namespace storm {
         }
         
         Dd<CUDD> DdManager<CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
-            std::vector<Dd<CUDD>> ddVariables = this->getMetaVariable(metaVariableName).getDdVariables();
+            // Check whether the meta variable exists.
+            if (!this->hasMetaVariable(metaVariableName)) {
+                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
+            }
+            
+            // Check whether the value is legal for this meta variable.
+            if (value < this->getMetaVariable(metaVariableName).getLow() || value > this->getMetaVariable(metaVariableName).getHigh()) {
+                throw storm::exceptions::InvalidArgumentException() << "Illegal value " << value << " for meta variable '" << metaVariableName << "'.";
+            }
+            
+            std::vector<Dd<CUDD>> const& ddVariables = this->getMetaVariable(metaVariableName).getDdVariables();
 
             Dd<CUDD> result;
             if (value & (1ull << (ddVariables.size() - 1))) {
@@ -120,7 +128,7 @@ namespace storm {
             auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
             
             if (!this->hasMetaVariable(metaVariableName)) {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name.";
+                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
             }
             
             return nameVariablePair->second;
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index a92dbc929..fb6856c75 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -36,7 +36,7 @@ TEST(CuddDdManager, Constants) {
     EXPECT_EQ(2, two.getMax());
 }
 
-TEST(CuddDdManager, MetaVariableTest) {
+TEST(CuddDdManager, AddMetaVariableTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
     
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
@@ -60,6 +60,29 @@ TEST(CuddDdManager, MetaVariableTest) {
     
     ASSERT_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x'"), storm::exceptions::InvalidArgumentException);
     ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
+}
+
+TEST(CuddDdManager, EncodingTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    
+    storm::dd::Dd<storm::dd::CUDD> encoding;
+    ASSERT_THROW(encoding = manager->getEncoding("x", 0), storm::exceptions::InvalidArgumentException);
+    ASSERT_THROW(encoding = manager->getEncoding("x", 10), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(encoding = manager->getEncoding("x", 4));
+    encoding.exportToDot("out.dot");
+    EXPECT_EQ(1, encoding.getNonZeroCount());
+    EXPECT_EQ(6, encoding.getNodeCount());
+    EXPECT_EQ(2, encoding.getLeafCount());
+}
+
+TEST(CuddDdMetaVariable, AccessorTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    EXPECT_EQ(1, manager->getNumberOfMetaVariables());
+    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
     storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x");
     
     EXPECT_EQ(1, metaVariableX.getLow());
@@ -69,3 +92,13 @@ TEST(CuddDdManager, MetaVariableTest) {
     EXPECT_EQ(4, metaVariableX.getNumberOfDdVariables());
 }
 
+//TEST(CuddDd, OperatorTest) {
+//    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+//    
+//    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+//    EXPECT_EQ(manager->getZero(), manager->getZero());
+//    EXPECT_NE(manager->getZero(), manager->getOne());
+//    
+//    storm::dd::Dd<storm::dd::CUDD> add;
+//    
+//}

From 0fce0444f77e0b653334fc9da5f7ccb6eb430b8b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 28 Mar 2014 20:53:02 +0100
Subject: [PATCH 046/147] Further bugfixes and tests for DD layer.

Former-commit-id: 32ef63f9b1316e69bbee0be31283686aba0f7526
---
 src/storage/dd/CuddDd.cpp              | 62 +++++++++++++++++---------
 src/storage/dd/CuddDd.h                | 15 +++++--
 src/storage/dd/CuddDdManager.cpp       | 36 ++++++++++++---
 src/storage/dd/CuddDdManager.h         | 13 +++++-
 test/functional/storage/CuddDdTest.cpp | 31 ++++++++++++-
 5 files changed, 124 insertions(+), 33 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index aa3b7c675..6fbf38a11 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -12,7 +12,7 @@ namespace storm {
         }
         
         bool Dd<CUDD>::operator==(Dd<CUDD> const& other) const {
-            return this->getCuddAdd() == other.getCuddAdd();
+            return this->cuddAdd == other.getCuddAdd();
         }
         
         Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
@@ -22,7 +22,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator+=(Dd<CUDD> const& other) {
-            this->getCuddAdd() += other.getCuddAdd();
+            this->cuddAdd += other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
             this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@@ -37,7 +37,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator*=(Dd<CUDD> const& other) {
-            this->getCuddAdd() *= other.getCuddAdd();
+            this->cuddAdd *= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
             this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@@ -52,7 +52,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator-=(Dd<CUDD> const& other) {
-            this->getCuddAdd() -= other.getCuddAdd();
+            this->cuddAdd -= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
             this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@@ -67,7 +67,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
-            this->getCuddAdd().Divide(other.getCuddAdd());
+            this->cuddAdd.Divide(other.getCuddAdd());
             
             // Join the variable sets of the two participating DDs.
             this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@@ -82,7 +82,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::complement() {
-            this->getCuddAdd() = ~this->getCuddAdd();
+            this->cuddAdd = ~this->cuddAdd;
             return *this;
         }
         
@@ -136,7 +136,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->getCuddAdd().OrAbstract(cubeDd.getCuddAdd());
+            this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
@@ -153,7 +153,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->getCuddAdd().ExistAbstract(cubeDd.getCuddAdd());
+            this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
@@ -170,7 +170,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->getCuddAdd().Minimum(cubeDd.getCuddAdd());
+            this->cuddAdd.Minimum(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
@@ -187,7 +187,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->getCuddAdd().Maximum(cubeDd.getCuddAdd());
+            this->cuddAdd.Maximum(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
@@ -223,7 +223,7 @@ namespace storm {
             }
             
             // Finally, call CUDD to swap the variables.
-            this->getCuddAdd().SwapVariables(from, to);
+            this->cuddAdd.SwapVariables(from, to);
         }
         
         Dd<CUDD> Dd<CUDD>::multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
@@ -241,7 +241,7 @@ namespace storm {
             std::set<std::string> containedMetaVariableNames;
             std::set_difference(unionOfMetaVariableNames.begin(), unionOfMetaVariableNames.end(), summationMetaVariableNames.begin(), summationMetaVariableNames.end(), std::inserter(containedMetaVariableNames, containedMetaVariableNames.begin()));
             
-            return Dd<CUDD>(this->getDdManager(), this->getCuddAdd().MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
+            return Dd<CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
         }
 
         
@@ -262,35 +262,55 @@ namespace storm {
         }
         
         double Dd<CUDD>::getMin() const {
-            ADD constantMinAdd = this->getCuddAdd().FindMin();
+            ADD constantMinAdd = this->cuddAdd.FindMin();
             return static_cast<double>(Cudd_V(constantMinAdd.getNode()));
         }
         
         double Dd<CUDD>::getMax() const {
-            ADD constantMaxAdd = this->getCuddAdd().FindMax();
+            ADD constantMaxAdd = this->cuddAdd.FindMax();
             return static_cast<double>(Cudd_V(constantMaxAdd.getNode()));
         }
         
         void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
-            std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
+            std::map<std::string, int_fast64_t> metaVariableNameToValueMap;
             metaVariableNameToValueMap.emplace(metaVariableName, variableValue);
             this->setValue(metaVariableNameToValueMap, targetValue);
         }
         
         void Dd<CUDD>::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) {
-            std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
+            std::map<std::string, int_fast64_t> metaVariableNameToValueMap;
             metaVariableNameToValueMap.emplace(metaVariableName1, variableValue1);
             metaVariableNameToValueMap.emplace(metaVariableName2, variableValue2);
             this->setValue(metaVariableNameToValueMap, targetValue);
         }
         
-        void Dd<CUDD>::setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
+        void Dd<CUDD>::setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
             Dd<CUDD> valueEncoding(this->getDdManager()->getOne());
             for (auto const& nameValuePair : metaVariableNameToValueMap) {
                 valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
+                // Also record that the DD now contains the meta variable.
+                this->addContainedMetaVariable(nameValuePair.first);
             }
             
-            this->getCuddAdd() = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
+            this->cuddAdd = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
+        }
+        
+        double Dd<CUDD>::getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const {
+            std::set<std::string> remainingMetaVariables(this->getContainedMetaVariableNames());
+            Dd<CUDD> valueEncoding(this->getDdManager()->getOne());
+            for (auto const& nameValuePair : metaVariableNameToValueMap) {
+                valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
+                if (this->containsMetaVariable(nameValuePair.first)) {
+                    remainingMetaVariables.erase(nameValuePair.first);
+                }
+            }
+            
+            if (!remainingMetaVariables.empty()) {
+                throw storm::exceptions::InvalidArgumentException() << "Cannot evaluate function for which not all inputs were given.";
+            }
+            
+            Dd<CUDD> value = *this * valueEncoding;
+            return static_cast<double>(Cudd_V(value.getCuddAdd().getNode()));
         }
         
         bool Dd<CUDD>::isOne() const {
@@ -327,15 +347,15 @@ namespace storm {
         
         void Dd<CUDD>::exportToDot(std::string const& filename) const {
             if (filename.empty()) {
-                this->getDdManager()->getCuddManager().DumpDot({this->getCuddAdd()});
+                this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd});
             } else {
                 FILE* filePointer = fopen(filename.c_str() , "w");
-                this->getDdManager()->getCuddManager().DumpDot({this->getCuddAdd()}, nullptr, nullptr, filePointer);
+                this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer);
                 fclose(filePointer);
             }
         }
         
-        ADD& Dd<CUDD>::getCuddAdd() {
+        ADD Dd<CUDD>::getCuddAdd() {
             return this->cuddAdd;
         }
         
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 0255ae58e..0a665108e 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -1,7 +1,7 @@
 #ifndef STORM_STORAGE_DD_CUDDDD_H_
 #define STORM_STORAGE_DD_CUDDDD_H_
 
-#include <unordered_map>
+#include <map>
 #include <set>
 #include <memory>
 #include <iostream>
@@ -295,7 +295,16 @@ namespace storm {
              * have. All values must be within the range of the respective meta variable.
              * @param targetValue The new function value of the modified encodings.
              */
-            void setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
+            void setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
+            
+            /*!
+             * Retrieves the value of the function when all meta variables are assigned the values of the given mapping.
+             * Note that the mapping must specify values for all meta variables contained in the DD.
+             *
+             * @param metaVariableNameToValueMap A mapping of meta variable names to their values.
+             * @return The value of the function evaluated with the given input.
+             */
+            double getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const;
             
             /*!
              * Retrieves whether this DD represents the constant one function.
@@ -362,7 +371,7 @@ namespace storm {
              *
              * @return The CUDD ADD object associated with this DD.
              */
-            ADD& getCuddAdd();
+            ADD getCuddAdd();
             
             /*!
              * Retrieves the CUDD ADD object associated with this DD.
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 4b96e685a..3c87157b2 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -28,18 +28,23 @@ namespace storm {
                 throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
             }
             
+            DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
+            
             // Check whether the value is legal for this meta variable.
-            if (value < this->getMetaVariable(metaVariableName).getLow() || value > this->getMetaVariable(metaVariableName).getHigh()) {
+            if (value < metaVariable.getLow() || value > metaVariable.getHigh()) {
                 throw storm::exceptions::InvalidArgumentException() << "Illegal value " << value << " for meta variable '" << metaVariableName << "'.";
             }
             
-            std::vector<Dd<CUDD>> const& ddVariables = this->getMetaVariable(metaVariableName).getDdVariables();
+            // Now compute the encoding relative to the low value of the meta variable.
+            value -= metaVariable.getLow();
+            
+            std::vector<Dd<CUDD>> const& ddVariables = metaVariable.getDdVariables();
 
             Dd<CUDD> result;
             if (value & (1ull << (ddVariables.size() - 1))) {
                 result = ddVariables[0];
             } else {
-                result = ddVariables[0];
+                result = ~ddVariables[0];
             }
             
             for (std::size_t i = 1; i < ddVariables.size(); ++i) {
@@ -49,16 +54,37 @@ namespace storm {
                     result *= ~ddVariables[i];
                 }
             }
+                        
+            return result;
+        }
+        
+        Dd<CUDD> DdManager<CUDD>::getRange(std::string const& metaVariableName) {
+            // Check whether the meta variable exists.
+            if (!this->hasMetaVariable(metaVariableName)) {
+                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
+            }
+
+            storm::dd::DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
+            
+            Dd<CUDD> result = this->getZero();
             
+            for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
+                result.setValue(metaVariableName, value, static_cast<double>(1));
+            }
             return result;
         }
         
-        Dd<CUDD> DdManager<CUDD>::getRange(std::string const metaVariableName) {
+        Dd<CUDD> DdManager<CUDD>::getIdentity(std::string const& metaVariableName) {
+            // Check whether the meta variable exists.
+            if (!this->hasMetaVariable(metaVariableName)) {
+                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
+            }
+            
             storm::dd::DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
             Dd<CUDD> result = this->getZero();
             for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
-                result.setValue(metaVariableName, value - metaVariable.getLow(), static_cast<double>(value));
+                result.setValue(metaVariableName, value, static_cast<double>(value));
             }
             return result;
         }
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 1d0d32a99..569ccf1c9 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -69,9 +69,18 @@ namespace storm {
              * of the range of the meta variable to one.
              *
              * @param metaVariableName The name of the meta variable whose range to retrieve.
-             * @return The range of the meta variable
+             * @return The range of the meta variable.
              */
-            Dd<CUDD> getRange(std::string const metaVariableName);
+            Dd<CUDD> getRange(std::string const& metaVariableName);
+
+            /*!
+             * Retrieves the DD representing the identity of the meta variable, i.e., a function that maps all legal
+             * values of the range of the meta variable to themselves.
+             *
+             * @param metaVariableName The name of the meta variable whose identity to retrieve.
+             * @return The identity of the meta variable.
+             */
+            Dd<CUDD> getIdentity(std::string const& metaVariableName);
             
             /*!
              * Adds a meta variable with the given name and range.
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index fb6856c75..245b1f283 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -36,7 +36,7 @@ TEST(CuddDdManager, Constants) {
     EXPECT_EQ(2, two.getMax());
 }
 
-TEST(CuddDdManager, AddMetaVariableTest) {
+TEST(CuddDdManager, AddGetMetaVariableTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
     
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
@@ -71,12 +71,39 @@ TEST(CuddDdManager, EncodingTest) {
     ASSERT_THROW(encoding = manager->getEncoding("x", 0), storm::exceptions::InvalidArgumentException);
     ASSERT_THROW(encoding = manager->getEncoding("x", 10), storm::exceptions::InvalidArgumentException);
     ASSERT_NO_THROW(encoding = manager->getEncoding("x", 4));
-    encoding.exportToDot("out.dot");
     EXPECT_EQ(1, encoding.getNonZeroCount());
     EXPECT_EQ(6, encoding.getNodeCount());
     EXPECT_EQ(2, encoding.getLeafCount());
 }
 
+TEST(CuddDdManager, RangeTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    
+    storm::dd::Dd<storm::dd::CUDD> range;
+    ASSERT_THROW(range = manager->getRange("y"), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(range = manager->getRange("x"));
+    
+    EXPECT_EQ(9, range.getNonZeroCount());
+    EXPECT_EQ(2, range.getLeafCount());
+    EXPECT_EQ(6, range.getNodeCount());
+}
+
+TEST(CuddDdManager, IdentityTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    
+    storm::dd::Dd<storm::dd::CUDD> range;
+    ASSERT_THROW(range = manager->getIdentity("y"), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(range = manager->getIdentity("x"));
+    
+    EXPECT_EQ(9, range.getNonZeroCount());
+    EXPECT_EQ(10, range.getLeafCount());
+    EXPECT_EQ(21, range.getNodeCount());
+}
+
 TEST(CuddDdMetaVariable, AccessorTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
     

From 88d9f36ef492528b88259e2c4fc6d5668544596c Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 29 Mar 2014 20:58:14 +0100
Subject: [PATCH 047/147] Added min/max abstract over DD variables to CUDD
 (actual code taken from PRISM). Added more tests for DD layer. Fixed some
 bugs in the DD layer.

Former-commit-id: a4b7810137eae9810f65de60dede0a17759becf3
---
 resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h |   2 +
 .../3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c | 261 ++++++++++++++++++
 .../3rdparty/cudd-2.5.0/src/cudd/cuddInt.h    |   2 +
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.cc    |  17 ++
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.hh    |   2 +
 src/storage/dd/CuddDd.cpp                     |  34 ++-
 src/storage/dd/CuddDd.h                       |  20 +-
 test/functional/storage/CuddDdTest.cpp        | 169 ++++++++++--
 8 files changed, 473 insertions(+), 34 deletions(-)

diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
index 8e3686170..5a2c2f952 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
@@ -767,6 +767,8 @@ extern int Cudd_bddVarIsBound (DdManager *dd, int index);
 extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube);
 extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube);
 extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * Cudd_addMinAbstract(DdManager * manager, DdNode * f, DdNode * cube);
+extern DdNode * Cudd_addMaxAbstract(DdManager * manager, DdNode * f, DdNode * cube);
 extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
 extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g);
 extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g);
diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
index 5e809c134..7d774586c 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
@@ -11,12 +11,16 @@
 		<li> Cudd_addExistAbstract()
 		<li> Cudd_addUnivAbstract()
 		<li> Cudd_addOrAbstract()
+        <li> Cudd_addMinAbstract()
+        <li> Cudd_addMaxAbstract()
 		</ul>
 	Internal procedures included in this module:
 		<ul>
 		<li> cuddAddExistAbstractRecur()
 		<li> cuddAddUnivAbstractRecur()
 		<li> cuddAddOrAbstractRecur()
+        <li> cuddAddMinAbstractRecur()
+        <li> cuddAddMaxAbstractRecur()
 		</ul>
 	Static procedures included in this module:
 		<ul>
@@ -229,6 +233,82 @@ Cudd_addOrAbstract(
 
 } /* end of Cudd_addOrAbstract */
 
+/**Function********************************************************************
+ 
+ Synopsis    [Abstracts all the variables in cube from the
+ ADD f by taking the minimum.]
+ 
+ Description [Abstracts all the variables in cube from the ADD f
+ by taking the minimum over all possible values taken by the
+ variables.  Returns the abstracted ADD if successful; NULL
+ otherwise.]
+ 
+ SideEffects [None]
+ 
+ SeeAlso     [Cudd_addUnivAbstract Cudd_addExistAbstract]
+ 
+ Note: Added by Dave Parker 14/6/99
+ 
+ ******************************************************************************/
+DdNode *
+Cudd_addMinAbstract(
+                    DdManager * manager,
+                    DdNode * f,
+                    DdNode * cube)
+{
+    DdNode *res;
+    
+    if (addCheckPositiveCube(manager, cube) == 0) {
+        (void) fprintf(manager->err,"Error: Can only abstract cubes");
+        return(NULL);
+    }
+    
+    do {
+        manager->reordered = 0;
+        res = cuddAddMinAbstractRecur(manager, f, cube);
+    } while (manager->reordered == 1);
+    return(res);
+    
+} /* end of Cudd_addMinAbstract */
+
+
+/**Function********************************************************************
+ 
+ Synopsis    [Abstracts all the variables in cube from the
+ ADD f by taking the maximum.]
+ 
+ Description [Abstracts all the variables in cube from the ADD f
+ by taking the maximum over all possible values taken by the
+ variables.  Returns the abstracted ADD if successful; NULL
+ otherwise.]
+ 
+ SideEffects [None]
+ 
+ SeeAlso     [Cudd_addUnivAbstract Cudd_addExistAbstract]
+ 
+ Note: Added by Dave Parker 14/6/99
+ 
+ ******************************************************************************/
+DdNode *
+Cudd_addMaxAbstract(
+                    DdManager * manager,
+                    DdNode * f,
+                    DdNode * cube)
+{
+    DdNode *res;
+    
+    if (addCheckPositiveCube(manager, cube) == 0) {
+        (void) fprintf(manager->err,"Error: Can only abstract cubes");
+        return(NULL);
+    }
+    
+    do {
+        manager->reordered = 0;
+        res = cuddAddMaxAbstractRecur(manager, f, cube);
+    } while (manager->reordered == 1);
+    return(res);
+    
+} /* end of Cudd_addMaxAbstract */
 
 /*---------------------------------------------------------------------------*/
 /* Definition of internal functions                                          */
@@ -542,7 +622,188 @@ cuddAddOrAbstractRecur(
 
 } /* end of cuddAddOrAbstractRecur */
 
+/**Function********************************************************************
+ 
+ Synopsis    [Performs the recursive step of Cudd_addMinAbstract.]
+ 
+ Description [Performs the recursive step of Cudd_addMinAbstract.
+ Returns the ADD obtained by abstracting the variables of cube from f,
+ if successful; NULL otherwise.]
+ 
+ SideEffects [None]
+ 
+ SeeAlso     []
+ 
+ ******************************************************************************/
+DdNode *
+cuddAddMinAbstractRecur(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+	DdNode	*T, *E, *res, *res1, *res2, *zero;
+    
+	zero = DD_ZERO(manager);
+    
+	/* Cube is guaranteed to be a cube at this point. */
+	if (f == zero || cuddIsConstant(cube)) {
+		return(f);
+	}
+    
+    /* Abstract a variable that does not appear in f. */
+	if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
+		res = cuddAddMinAbstractRecur(manager, f, cuddT(cube));
+       	return(res);
+	}
+    
+	if ((res = cuddCacheLookup2(manager, Cudd_addMinAbstract, f, cube)) != NULL) {
+		return(res);
+	}
+    
+    
+	T = cuddT(f);
+	E = cuddE(f);
+    
+	/* If the two indices are the same, so are their levels. */
+	if (f->index == cube->index) {
+		res1 = cuddAddMinAbstractRecur(manager, T, cuddT(cube));
+		if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+		res2 = cuddAddMinAbstractRecur(manager, E, cuddT(cube));
+		if (res2 == NULL) {
+            Cudd_RecursiveDeref(manager,res1);
+            return(NULL);
+		}
+		cuddRef(res2);
+		res = cuddAddApplyRecur(manager, Cudd_addMinimum, res1, res2);
+		if (res == NULL) {
+            Cudd_RecursiveDeref(manager,res1);
+            Cudd_RecursiveDeref(manager,res2);
+            return(NULL);
+		}
+		cuddRef(res);
+		Cudd_RecursiveDeref(manager,res1);
+		Cudd_RecursiveDeref(manager,res2);
+		cuddCacheInsert2(manager, Cudd_addMinAbstract, f, cube, res);
+		cuddDeref(res);
+        return(res);
+    }
+	else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
+		res1 = cuddAddMinAbstractRecur(manager, T, cube);
+		if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+		res2 = cuddAddMinAbstractRecur(manager, E, cube);
+		if (res2 == NULL) {
+			Cudd_RecursiveDeref(manager,res1);
+			return(NULL);
+		}
+        cuddRef(res2);
+		res = (res1 == res2) ? res1 :
+        cuddUniqueInter(manager, (int) f->index, res1, res2);
+		if (res == NULL) {
+            Cudd_RecursiveDeref(manager,res1);
+            Cudd_RecursiveDeref(manager,res2);
+            return(NULL);
+		}
+		cuddDeref(res1);
+		cuddDeref(res2);
+		cuddCacheInsert2(manager, Cudd_addMinAbstract, f, cube, res);
+        return(res);
+	}
+    
+} /* end of cuddAddMinAbstractRecur */
+
 
+/**Function********************************************************************
+ 
+ Synopsis    [Performs the recursive step of Cudd_addMaxAbstract.]
+ 
+ Description [Performs the recursive step of Cudd_addMaxAbstract.
+ Returns the ADD obtained by abstracting the variables of cube from f,
+ if successful; NULL otherwise.]
+ 
+ SideEffects [None]
+ 
+ SeeAlso     []
+ 
+ ******************************************************************************/
+DdNode *
+cuddAddMaxAbstractRecur(
+                        DdManager * manager,
+                        DdNode * f,
+                        DdNode * cube)
+{
+	DdNode	*T, *E, *res, *res1, *res2, *zero;
+    
+	zero = DD_ZERO(manager);
+    
+	/* Cube is guaranteed to be a cube at this point. */
+	if (f == zero || cuddIsConstant(cube)) {
+		return(f);
+	}
+    
+    /* Abstract a variable that does not appear in f. */
+	if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
+		res = cuddAddMaxAbstractRecur(manager, f, cuddT(cube));
+       	return(res);
+	}
+    
+	if ((res = cuddCacheLookup2(manager, Cudd_addMaxAbstract, f, cube)) != NULL) {
+		return(res);
+	}
+    
+    
+	T = cuddT(f);
+	E = cuddE(f);
+    
+	/* If the two indices are the same, so are their levels. */
+	if (f->index == cube->index) {
+		res1 = cuddAddMaxAbstractRecur(manager, T, cuddT(cube));
+		if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+		res2 = cuddAddMaxAbstractRecur(manager, E, cuddT(cube));
+		if (res2 == NULL) {
+            Cudd_RecursiveDeref(manager,res1);
+            return(NULL);
+		}
+		cuddRef(res2);
+		res = cuddAddApplyRecur(manager, Cudd_addMaximum, res1, res2);
+		if (res == NULL) {
+            Cudd_RecursiveDeref(manager,res1);
+            Cudd_RecursiveDeref(manager,res2);
+            return(NULL);
+		}
+		cuddRef(res);
+		Cudd_RecursiveDeref(manager,res1);
+		Cudd_RecursiveDeref(manager,res2);
+		cuddCacheInsert2(manager, Cudd_addMaxAbstract, f, cube, res);
+		cuddDeref(res);
+        return(res);
+    }
+	else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
+		res1 = cuddAddMaxAbstractRecur(manager, T, cube);
+		if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+		res2 = cuddAddMaxAbstractRecur(manager, E, cube);
+		if (res2 == NULL) {
+			Cudd_RecursiveDeref(manager,res1);
+			return(NULL);
+		}
+        cuddRef(res2);
+		res = (res1 == res2) ? res1 :
+        cuddUniqueInter(manager, (int) f->index, res1, res2);
+		if (res == NULL) {
+            Cudd_RecursiveDeref(manager,res1);
+            Cudd_RecursiveDeref(manager,res2);
+            return(NULL);
+		}
+		cuddDeref(res1);
+		cuddDeref(res2);
+		cuddCacheInsert2(manager, Cudd_addMaxAbstract, f, cube, res);
+        return(res);
+	}	    
+    
+} /* end of cuddAddMaxAbstractRecur */
 
 /*---------------------------------------------------------------------------*/
 /* Definition of static functions                                            */
diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
index 398b057f7..313a56586 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
@@ -1000,6 +1000,8 @@ dd->nextSample += 250000;}
 extern DdNode * cuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
 extern DdNode * cuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
 extern DdNode * cuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * cuddAddMinAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * cuddAddMaxAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
 extern DdNode * cuddAddApplyRecur (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
 extern DdNode * cuddAddMonadicApplyRecur (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f);
 extern DdNode * cuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon);
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
index ffbaaf826..c9fcf7b11 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
@@ -2405,6 +2405,23 @@ ADD::OrAbstract(
 
 } // ADD::OrAbstract
 
+ADD
+ADD::MinAbstract(const ADD& cube) const
+{
+    DdManager *mgr = checkSameManager(cube);
+    DdNode *result = Cudd_addMinAbstract(mgr, node, cube.node);
+    checkReturnValue(result);
+    return ADD(p, result);
+} // ADD::MinAbstract
+
+ADD
+ADD::MaxAbstract(const ADD& cube) const
+{
+    DdManager *mgr = checkSameManager(cube);
+    DdNode *result = Cudd_addMaxAbstract(mgr, node, cube.node);
+    checkReturnValue(result);
+    return ADD(p, result);
+} // ADD::MaxAbstract
 
 ADD
 ADD::Plus(
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
index 0dce65989..a1a859490 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
@@ -373,6 +373,8 @@ public:
     ADD ExistAbstract(const ADD& cube) const;
     ADD UnivAbstract(const ADD& cube) const;
     ADD OrAbstract(const ADD& cube) const;
+    ADD MinAbstract(const ADD& cube) const;
+    ADD MaxAbstract(const ADD& cube) const;
     ADD Plus(const ADD& g) const;
     ADD Times(const ADD& g) const;
     ADD Threshold(const ADD& g) const;
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 6fbf38a11..d2c69c3c5 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -15,6 +15,10 @@ namespace storm {
             return this->cuddAdd == other.getCuddAdd();
         }
         
+        bool Dd<CUDD>::operator!=(Dd<CUDD> const& other) const {
+            return this->cuddAdd == other.getCuddAdd();
+        }
+        
         Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
             result += other;
@@ -67,7 +71,7 @@ namespace storm {
         }
         
         Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
-            this->cuddAdd.Divide(other.getCuddAdd());
+            this->cuddAdd = this->cuddAdd.Divide(other.getCuddAdd());
             
             // Join the variable sets of the two participating DDs.
             this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@@ -88,37 +92,37 @@ namespace storm {
         
         Dd<CUDD> Dd<CUDD>::equals(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
-            result.getCuddAdd().Equals(other.getCuddAdd());
+            result.cuddAdd = result.cuddAdd.Equals(other.getCuddAdd());
             return result;
         }
         
         Dd<CUDD> Dd<CUDD>::notEquals(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
-            result.getCuddAdd().NotEquals(other.getCuddAdd());
+            result.cuddAdd = result.cuddAdd.NotEquals(other.getCuddAdd());
             return result;
         }
         
         Dd<CUDD> Dd<CUDD>::less(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
-            result.getCuddAdd().LessThan(other.getCuddAdd());
+            result.cuddAdd = result.cuddAdd.LessThan(other.getCuddAdd());
             return result;
         }
         
         Dd<CUDD> Dd<CUDD>::lessOrEqual(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
-            result.getCuddAdd().LessThanOrEqual(other.getCuddAdd());
+            result.cuddAdd = result.cuddAdd.LessThanOrEqual(other.getCuddAdd());
             return result;
         }
         
         Dd<CUDD> Dd<CUDD>::greater(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
-            result.getCuddAdd().GreaterThan(other.getCuddAdd());
+            result.cuddAdd = result.cuddAdd.GreaterThan(other.getCuddAdd());
             return result;
         }
         
         Dd<CUDD> Dd<CUDD>::greaterOrEqual(Dd<CUDD> const& other) const {
             Dd<CUDD> result(*this);
-            result.getCuddAdd().GreaterThanOrEqual(other.getCuddAdd());
+            result.cuddAdd = result.cuddAdd.GreaterThanOrEqual(other.getCuddAdd());
             return result;
         }
         
@@ -136,7 +140,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
+            this->cuddAdd = this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
@@ -153,7 +157,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
+            this->cuddAdd = this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
@@ -170,7 +174,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd.Minimum(cubeDd.getCuddAdd());
+            this->cuddAdd = this->cuddAdd.MinAbstract(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
@@ -187,7 +191,7 @@ namespace storm {
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd.Maximum(cubeDd.getCuddAdd());
+            this->cuddAdd = this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd());
         }
         
         void Dd<CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
@@ -223,7 +227,7 @@ namespace storm {
             }
             
             // Finally, call CUDD to swap the variables.
-            this->cuddAdd.SwapVariables(from, to);
+            this->cuddAdd = this->cuddAdd.SwapVariables(from, to);
         }
         
         Dd<CUDD> Dd<CUDD>::multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
@@ -243,7 +247,6 @@ namespace storm {
             
             return Dd<CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
         }
-
         
         uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
@@ -310,6 +313,7 @@ namespace storm {
             }
             
             Dd<CUDD> value = *this * valueEncoding;
+            value.sumAbstract(this->getContainedMetaVariableNames());
             return static_cast<double>(Cudd_V(value.getCuddAdd().getNode()));
         }
         
@@ -321,6 +325,10 @@ namespace storm {
             return *this == this->getDdManager()->getZero();
         }
         
+        bool Dd<CUDD>::isConstant() const {
+            return Cudd_IsConstant(this->cuddAdd.getNode());
+        }
+        
         bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
             auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
             return metaVariable != containedMetaVariableNames.end();
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 0a665108e..80cf88f3a 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -36,9 +36,18 @@ namespace storm {
              * Retrieves whether the two DDs represent the same function.
              *
              * @param other The DD that is to be compared with the current one.
+             * @return True if the DDs represent the same function.
              */
             bool operator==(Dd<CUDD> const& other) const;
             
+            /*!
+             * Retrieves whether the two DDs represent different functions.
+             *
+             * @param other The DD that is to be compared with the current one.
+             * @return True if the DDs represent the different functions.
+             */
+            bool operator!=(Dd<CUDD> const& other) const;
+            
             /*!
              * Adds the two DDs.
              *
@@ -295,7 +304,7 @@ namespace storm {
              * have. All values must be within the range of the respective meta variable.
              * @param targetValue The new function value of the modified encodings.
              */
-            void setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
+            void setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap = std::map<std::string, int_fast64_t>(), double targetValue = 0);
             
             /*!
              * Retrieves the value of the function when all meta variables are assigned the values of the given mapping.
@@ -304,7 +313,7 @@ namespace storm {
              * @param metaVariableNameToValueMap A mapping of meta variable names to their values.
              * @return The value of the function evaluated with the given input.
              */
-            double getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const;
+            double getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap = std::map<std::string, int_fast64_t>()) const;
             
             /*!
              * Retrieves whether this DD represents the constant one function.
@@ -320,6 +329,13 @@ namespace storm {
              */
             bool isZero() const;
             
+            /*!
+             * Retrieves whether this DD represents a constant function.
+             *
+             * @return True if this DD represents a constants function.
+             */
+            bool isConstant() const;
+            
             /*!
              * Retrieves whether the given meta variable is contained in the DD.
              *
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 245b1f283..959bc5db0 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -7,7 +7,6 @@
 
 TEST(CuddDdManager, Constants) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    
     storm::dd::Dd<storm::dd::CUDD> zero;
     ASSERT_NO_THROW(zero = manager->getZero());
     
@@ -38,7 +37,6 @@ TEST(CuddDdManager, Constants) {
 
 TEST(CuddDdManager, AddGetMetaVariableTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
     EXPECT_EQ(1, manager->getNumberOfMetaVariables());
     
@@ -64,8 +62,7 @@ TEST(CuddDdManager, AddGetMetaVariableTest) {
 
 TEST(CuddDdManager, EncodingTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    
-    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    manager->addMetaVariable("x", 1, 9);
     
     storm::dd::Dd<storm::dd::CUDD> encoding;
     ASSERT_THROW(encoding = manager->getEncoding("x", 0), storm::exceptions::InvalidArgumentException);
@@ -78,7 +75,6 @@ TEST(CuddDdManager, EncodingTest) {
 
 TEST(CuddDdManager, RangeTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
     
     storm::dd::Dd<storm::dd::CUDD> range;
@@ -92,8 +88,7 @@ TEST(CuddDdManager, RangeTest) {
 
 TEST(CuddDdManager, IdentityTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    
-    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    manager->addMetaVariable("x", 1, 9);
     
     storm::dd::Dd<storm::dd::CUDD> range;
     ASSERT_THROW(range = manager->getIdentity("y"), storm::exceptions::InvalidArgumentException);
@@ -106,8 +101,7 @@ TEST(CuddDdManager, IdentityTest) {
 
 TEST(CuddDdMetaVariable, AccessorTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    
-    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
+    manager->addMetaVariable("x", 1, 9);
     EXPECT_EQ(1, manager->getNumberOfMetaVariables());
     ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
     storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x");
@@ -119,13 +113,150 @@ TEST(CuddDdMetaVariable, AccessorTest) {
     EXPECT_EQ(4, metaVariableX.getNumberOfDdVariables());
 }
 
-//TEST(CuddDd, OperatorTest) {
-//    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-//    
-//    ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
-//    EXPECT_EQ(manager->getZero(), manager->getZero());
-//    EXPECT_NE(manager->getZero(), manager->getOne());
-//    
-//    storm::dd::Dd<storm::dd::CUDD> add;
-//    
-//}
+TEST(CuddDd, OperatorTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    manager->addMetaVariable("x", 1, 9);
+    EXPECT_TRUE(manager->getZero() == manager->getZero());
+    EXPECT_FALSE(manager->getZero() == manager->getOne());
+    
+    storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getOne();
+    storm::dd::Dd<storm::dd::CUDD> dd2 = manager->getOne();
+    storm::dd::Dd<storm::dd::CUDD> dd3 = dd1 + dd2;
+    EXPECT_TRUE(dd3 == manager->getConstant(2));
+    
+    dd3 += manager->getZero();
+    EXPECT_TRUE(dd3 == manager->getConstant(2));
+    
+    dd3 = dd1 * manager->getConstant(3);
+    EXPECT_TRUE(dd3 == manager->getConstant(3));
+    
+    dd3 *= manager->getConstant(2);
+    EXPECT_TRUE(dd3 == manager->getConstant(6));
+    
+    dd3 = dd1 - dd2;
+    EXPECT_TRUE(dd3 == manager->getZero());
+    
+    dd3 -= manager->getConstant(-2);
+    EXPECT_TRUE(dd3 == manager->getConstant(2));
+    
+    dd3 /= manager->getConstant(2);
+    EXPECT_TRUE(dd3 == manager->getOne());
+    
+    dd3.complement();
+    EXPECT_TRUE(dd3 == manager->getZero());
+    
+    dd1 = ~dd3;
+    EXPECT_TRUE(dd1 == manager->getOne());
+    
+    dd1 = manager->getIdentity("x");
+    dd2 = manager->getConstant(5);
+
+    dd3 = dd1.equals(dd2);
+    EXPECT_EQ(1, dd3.getNonZeroCount());
+    
+    storm::dd::Dd<storm::dd::CUDD> dd4 = dd1.notEquals(dd2);
+    EXPECT_TRUE(dd4 == ~dd3);
+    
+    dd3 = dd1.less(dd2);
+    EXPECT_EQ(11, dd3.getNonZeroCount());
+    
+    dd3 = dd1.lessOrEqual(dd2);
+    EXPECT_EQ(12, dd3.getNonZeroCount());
+    
+    dd3 = dd1.greater(dd2);
+    EXPECT_EQ(4, dd3.getNonZeroCount());
+
+    dd3 = dd1.greaterOrEqual(dd2);
+    EXPECT_EQ(5, dd3.getNonZeroCount());
+}
+
+TEST(CuddDd, AbstractionTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+    storm::dd::Dd<storm::dd::CUDD> dd1;
+    storm::dd::Dd<storm::dd::CUDD> dd2;
+    storm::dd::Dd<storm::dd::CUDD> dd3;
+    
+    dd1 = manager->getIdentity("x");
+    dd2 = manager->getConstant(5);
+    dd3 = dd1.equals(dd2);
+    EXPECT_EQ(1, dd3.getNonZeroCount());
+    ASSERT_THROW(dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3.existsAbstract({"x"}));
+    EXPECT_EQ(1, dd3.getNonZeroCount());
+    EXPECT_EQ(1, dd3.getMax());
+
+    dd3 = dd1.equals(dd2);
+    dd3 *= manager->getConstant(3);
+    EXPECT_EQ(1, dd3.getNonZeroCount());
+    ASSERT_THROW(dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3.existsAbstract({"x"}));
+    EXPECT_TRUE(dd3 == manager->getZero());
+
+    dd3 = dd1.equals(dd2);
+    dd3 *= manager->getConstant(3);
+    ASSERT_THROW(dd3.sumAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3.sumAbstract({"x"}));
+    EXPECT_EQ(1, dd3.getNonZeroCount());
+    EXPECT_EQ(3, dd3.getMax());
+
+    dd3 = dd1.equals(dd2);
+    dd3 *= manager->getConstant(3);
+    ASSERT_THROW(dd3.minAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3.minAbstract({"x"}));
+    EXPECT_EQ(0, dd3.getNonZeroCount());
+    EXPECT_EQ(0, dd3.getMax());
+
+    dd3 = dd1.equals(dd2);
+    dd3 *= manager->getConstant(3);
+    ASSERT_THROW(dd3.maxAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3.maxAbstract({"x"}));
+    EXPECT_EQ(1, dd3.getNonZeroCount());
+    EXPECT_EQ(3, dd3.getMax());
+}
+
+TEST(CuddDd, SwapTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    
+    manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+    manager->addMetaVariable("z", 2, 8);
+    storm::dd::Dd<storm::dd::CUDD> dd1;
+    storm::dd::Dd<storm::dd::CUDD> dd2;
+    
+    dd1 = manager->getIdentity("x");
+    ASSERT_THROW(dd1.swapVariables({std::make_pair("x", "z")}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd1.swapVariables({std::make_pair("x", "x'")}));
+    EXPECT_TRUE(dd1 == manager->getIdentity("x'"));
+}
+
+TEST(CuddDd, MultiplyMatrixTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+    
+    storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getIdentity("x").equals(manager->getIdentity("x'"));
+    storm::dd::Dd<storm::dd::CUDD> dd2 = manager->getRange("x'");
+    storm::dd::Dd<storm::dd::CUDD> dd3;
+    dd1 *= manager->getConstant(2);
+    
+    ASSERT_NO_THROW(dd3 = dd1.multiplyMatrix(dd2, {"x'"}));
+    ASSERT_NO_THROW(dd3.swapVariables({std::make_pair("x", "x'")}));
+    EXPECT_TRUE(dd3 == dd2 * manager->getConstant(2));
+}
+
+TEST(CuddDd, GetSetValueTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    manager->addMetaVariable("x", 1, 9);
+    
+    storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getOne();
+    ASSERT_NO_THROW(dd1.setValue("x", 4, 2));
+    EXPECT_EQ(2, dd1.getLeafCount());
+    dd1.exportToDot("dd1.dot");
+    
+    std::map<std::string, int_fast64_t> metaVariableToValueMap;
+    metaVariableToValueMap.emplace("x", 1);
+    EXPECT_EQ(1, dd1.getValue(metaVariableToValueMap));
+    
+    metaVariableToValueMap.clear();
+    metaVariableToValueMap.emplace("x", 4);
+    EXPECT_EQ(2, dd1.getValue(metaVariableToValueMap));
+}

From a55d5e27828962883583204ad1a4960fab9bbe0f Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Sat, 29 Mar 2014 23:40:41 +0100
Subject: [PATCH 048/147] Fixed an ambiguous call to a constructor with
 initlists - poor GCC.

Former-commit-id: 8a8df68ad703b7c11135acc43e345cbe494e7997
---
 src/storage/dd/CuddDd.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index d2c69c3c5..2560e1db0 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -358,7 +358,8 @@ namespace storm {
                 this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd});
             } else {
                 FILE* filePointer = fopen(filename.c_str() , "w");
-                this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer);
+				std::vector<ADD> cuddAddVector = { this->cuddAdd };
+				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, nullptr, nullptr, filePointer);
                 fclose(filePointer);
             }
         }

From 7845a52ef4cb89e1ff884aba30baacd5b440bb26 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Sat, 29 Mar 2014 23:45:46 +0100
Subject: [PATCH 049/147] Fixed a human error. Fixed the same ambiguous call
 error in the second place.

Former-commit-id: b9fff85b677921ede4553944075fd045ada50573
---
 src/storage/dd/CuddDd.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 2560e1db0..97ca50507 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -354,11 +354,11 @@ namespace storm {
         }
         
         void Dd<CUDD>::exportToDot(std::string const& filename) const {
-            if (filename.empty()) {
-                this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd});
+			std::vector<ADD> cuddAddVector = { this->cuddAdd };
+			if (filename.empty()) {
+				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector);
             } else {
                 FILE* filePointer = fopen(filename.c_str() , "w");
-				std::vector<ADD> cuddAddVector = { this->cuddAdd };
 				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, nullptr, nullptr, filePointer);
                 fclose(filePointer);
             }

From 33cce28df82a6399eb70dad51707d675c96fefe5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 30 Mar 2014 23:29:56 +0200
Subject: [PATCH 050/147] Fixed minor bug MILP-based minimal command set
 generator. GurobiLpSolver is now able to deal with constraints involving
 several instances of the same variable.

Former-commit-id: 4b5575a886b16c99bd9c8ee7f4a724e6fd58cefd
---
 .../MILPMinimalLabelSetGenerator.h            |  3 +-
 src/solver/GurobiLpSolver.cpp                 | 30 +++++++++++++++----
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index de9c6b057..b73ff1590 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -92,8 +92,7 @@ namespace storm {
                 StateInformation result;
                 result.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
                 result.relevantStates &= ~psiStates;
-                result.problematicStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
-                result.problematicStates.complement();
+                result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
                 result.problematicStates &= result.relevantStates;
                 LOG4CPLUS_DEBUG(logger, "Found " << phiStates.getNumberOfSetBits() << " filter states.");
                 LOG4CPLUS_DEBUG(logger, "Found " << psiStates.getNumberOfSetBits() << " target states.");
diff --git a/src/solver/GurobiLpSolver.cpp b/src/solver/GurobiLpSolver.cpp
index c06233942..75a0d5a7e 100644
--- a/src/solver/GurobiLpSolver.cpp
+++ b/src/solver/GurobiLpSolver.cpp
@@ -1,6 +1,7 @@
 #include "src/solver/GurobiLpSolver.h"
 
 #ifdef STORM_HAVE_GUROBI
+#include <numeric>
 
 #include "src/exceptions/InvalidStateException.h"
 #include "src/settings/Settings.h"
@@ -162,12 +163,29 @@ namespace storm {
                 throw storm::exceptions::InvalidStateException() << "Sizes of variable indices vector and coefficients vector do not match.";
             }
             
-            // Convert the uint vector to ints for proper input to Gurobi.
-            std::vector<int> variablesCopy(variables.begin(), variables.end());
+            // As Gurobi requires the indices to be unique, we now explicitly make them unique. For this, we sort the
+            // variables and coefficients and eliminated duplicates by adding the coefficients.
             
-            // Copy the coefficients, because Gurobi does not take the coefficients as const values. The alternative to this would be casting
-            // away the constness, which gives undefined behaviour if Gurobi actually modifies something.
-            std::vector<double> coefficientsCopy(coefficients);
+            // We start by sorting both vectors.
+            std::vector<uint_fast64_t> sortedVariables(variables);
+			std::vector<double> sortedCoefficients(coefficients);
+            std::vector<uint_fast64_t> permutation(variables.size());
+            std::iota(permutation.begin(), permutation.end(), 0);
+            std::sort(permutation.begin(), permutation.end(), [&] (uint_fast64_t i, uint_fast64_t j) { return variables[i] < variables[j]; } );
+            std::transform(permutation.begin(), permutation.end(), sortedVariables.begin(), [&] (uint_fast64_t i) { return variables[i]; } );
+            std::transform(permutation.begin(), permutation.end(), sortedCoefficients.begin(), [&] (uint_fast64_t i) { return coefficients[i]; } );
+            
+            // Now we perform the duplicate elimination step.
+            std::vector<int> uniqueVariables;
+            std::vector<double> uniqueCoefficients;
+			for (uint_fast64_t i = 0; i < sortedVariables.size(); ++i) {
+				if (!uniqueVariables.empty() && uniqueVariables.back() == sortedVariables[i]) {
+					uniqueCoefficients.back() += sortedCoefficients[i];
+                } else {
+					uniqueVariables.push_back(static_cast<int>(sortedVariables[i]));
+					uniqueCoefficients.push_back(sortedCoefficients[i]);
+                }
+            }
             
             bool strictBound = boundType == LESS || boundType == GREATER;
             char sense = boundType == LESS || boundType == LESS_EQUAL ? GRB_LESS_EQUAL : boundType == EQUAL ? GRB_EQUAL : GRB_GREATER_EQUAL;
@@ -181,7 +199,7 @@ namespace storm {
                     rightHandSideValue += storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble();
                 }
             }
-            int error = GRBaddconstr(model, variablesCopy.size(), variablesCopy.data(), coefficientsCopy.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
+            int error = GRBaddconstr(model, uniqueVariables.size(), uniqueVariables.data(), uniqueCoefficients.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
             
             if (error) {
                 LOG4CPLUS_ERROR(logger, "Unable to assert Gurobi constraint (" << GRBgeterrormsg(env) << ", error code " << error << ").");

From c8a8beca2a4e0d55d831f5e4ae95521a70fd2a70 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 31 Mar 2014 16:55:46 +0200
Subject: [PATCH 051/147] Started working on new easy-to-use expression
 classes.

Former-commit-id: 9ee1be58227286db4e7691705e6e92f8a1fca87b
---
 CMakeLists.txt                              |  2 +
 src/storage/expressions/BaseExpression.h    | 26 +++++++++++++
 src/storage/expressions/Expression.cpp      | 13 +++++++
 src/storage/expressions/Expression.h        | 42 +++++++++++++++++++++
 src/storage/expressions/SimpleValuation.cpp | 29 ++++++++++++++
 src/storage/expressions/SimpleValuation.h   | 40 ++++++++++++++++++++
 src/storage/expressions/Valuation.h         | 15 ++++++++
 test/functional/storage/ExpressionTest.cpp  |  9 +++++
 8 files changed, 176 insertions(+)
 create mode 100644 src/storage/expressions/BaseExpression.h
 create mode 100644 src/storage/expressions/Expression.cpp
 create mode 100644 src/storage/expressions/Expression.h
 create mode 100644 src/storage/expressions/SimpleValuation.cpp
 create mode 100644 src/storage/expressions/SimpleValuation.h
 create mode 100644 src/storage/expressions/Valuation.h
 create mode 100644 test/functional/storage/ExpressionTest.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 09eef57a9..7913af7d7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -251,6 +251,7 @@ file(GLOB_RECURSE STORM_SETTINGS_FILES ${PROJECT_SOURCE_DIR}/src/settings/*.h ${
 file(GLOB_RECURSE STORM_SOLVER_FILES ${PROJECT_SOURCE_DIR}/src/solver/*.h ${PROJECT_SOURCE_DIR}/src/solver/*.cpp)
 file(GLOB STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp)
 file(GLOB_RECURSE STORM_STORAGE_DD_FILES ${PROJECT_SOURCE_DIR}/src/storage/dd/*.h ${PROJECT_SOURCE_DIR}/src/storage/dd/*.cpp)
+file(GLOB_RECURSE STORM_STORAGE_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/storage/expressions/*.h ${PROJECT_SOURCE_DIR}/src/storage/expressions/*.cpp)
 file(GLOB_RECURSE STORM_UTILITY_FILES ${PROJECT_SOURCE_DIR}/src/utility/*.h ${PROJECT_SOURCE_DIR}/src/utility/*.cpp)
 file(GLOB STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp)
 file(GLOB_RECURSE STORM_IR_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.h ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.cpp)
@@ -284,6 +285,7 @@ source_group(settings FILES ${STORM_SETTINGS_FILES})
 source_group(solver FILES ${STORM_SOLVER_FILES})
 source_group(storage FILES ${STORM_STORAGE_FILES})
 source_group(storage\\dd FILES ${STORM_STORAGE_DD_FILES})
+source_group(storage\\expressions FILES ${STORM_STORAGE_EXPRESSIONS_FILES})
 source_group(utility FILES ${STORM_UTILITY_FILES})
 source_group(functional-test FILES ${STORM_FUNCTIONAL_TEST_FILES})
 source_group(performance-test FILES ${STORM_PERFORMANCE_TEST_FILES})
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
new file mode 100644
index 000000000..85b521726
--- /dev/null
+++ b/src/storage/expressions/BaseExpression.h
@@ -0,0 +1,26 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
+
+#include "src/storage/expressions/Valuation.h"
+
+namespace storm {
+    namespace expressions {
+        class BaseExpression {
+        public:
+            /*!
+             * Each node in an expression tree has a uniquely defined type from this enum.
+             */
+            enum ReturnType {undefined, bool_, int_, double_};
+            
+            std::unique_ptr<BaseExpression> substitute() const = 0;
+            
+            virtual int_fast64_t evaluateAsInt(Evaluation const& evaluation) const = 0;
+            
+            virtual bool evaluateAsBool(Evaluation const& evaluation) const = 0;
+            
+            virtual double evaluateAsDouble(Evaluation const& evaluation) const = 0;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
new file mode 100644
index 000000000..335fa3ca7
--- /dev/null
+++ b/src/storage/expressions/Expression.cpp
@@ -0,0 +1,13 @@
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace expressions {
+        virtual Expression Expression::operator+(Expression const& other) {
+            return Expression(this->getBaseExpression() + other.getBaseExpression());
+        }
+        
+        BaseExpression const& getBaseExpression() const {
+            return *this->expressionPtr;
+        }
+    }
+}
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
new file mode 100644
index 000000000..c44219736
--- /dev/null
+++ b/src/storage/expressions/Expression.h
@@ -0,0 +1,42 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
+
+namespace storm {
+    namespace expressions {
+        class Expression {
+            Expression() = default;
+            
+            // Static factory methods to create atomic expression parts.
+            
+            // Virtual operator overloading.
+            virtual Expression operator+(Expression const& other);
+            
+            /*!
+             * Substitutes all occurrences of identifiers according to the given substitution. Note that this
+             * substitution is done simultaneously, i.e., identifiers appearing in the expressions that were "plugged
+             * in" are not substituted.
+             *
+             * @param substitutionFilter A function that returns true iff the given identifier is supposed to be
+             * substituted.
+             * @param substitution A substitution that returns for each identifier an expression that is supposed to
+             * replace the identifier.
+             * @return An expression in which all identifiers
+             */
+            Expression substitute(std::function<Expression (std::string const&)> const& substitution) const;
+            
+        private:
+            /*!
+             * Retrieves the base expression underlying this expression object. Note that prior to calling this, the
+             * expression object must be properly initialized.
+             *
+             * @return A reference to the underlying base expression.
+             */
+            BaseExpression const& getBaseExpression() const;
+            
+            // A pointer to the underlying base expression.
+            std::unique_ptr<BaseExpression> expressionPtr;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
new file mode 100644
index 000000000..20c9f9f2f
--- /dev/null
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -0,0 +1,29 @@
+#include "src/storage/expressions/SimpleValuation.h"
+
+namespace storm {
+    namespace expressions {
+        SimpleValuation::SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount) : identifierToIndexMap(), booleanValues(booleanVariableCount), integerValues(integerVariableCount), doubleValues(doubleVariableCount) {
+            // Intentionally left empty.
+        }
+        
+        SimpleValuation::SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues) : identifierToIndexMap(identifierToIndexMap), booleanValues(booleanValues), integerValues(integerValues), doubleValues(doubleValues) {
+            // Intentionally left empty.
+        }
+
+        void SimpleValuation::setIdentifierIndex(std::string const& name, uint_fast64_t index) {
+            (*this->identifierToIndexMap)[name] = index;
+        }
+        
+        bool SimpleValuation::getBooleanValue(std::string const& name) const {
+            return false;
+        }
+        
+        int_fast64_t SimpleValuation::getIntegerValue(std::string const& name) const {
+            return 0;
+        }
+        
+        double SimpleValuation::getDoubleValue(std::string const& name) const {
+            return 0.0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
new file mode 100644
index 000000000..fd7d3c8b0
--- /dev/null
+++ b/src/storage/expressions/SimpleValuation.h
@@ -0,0 +1,40 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_SIMPLEVALUATION_H_
+#define STORM_STORAGE_EXPRESSIONS_SIMPLEVALUATION_H_
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <unordered_map>
+
+#include "src/storage/expressions/Valuation.h"
+
+namespace storm {
+    namespace expressions {
+        class SimpleValuation : public Valuation {
+        public:
+            SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount);
+            
+            SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues);
+
+            SimpleValuation() = default;
+            SimpleValuation(SimpleValuation const&) = default;
+            SimpleValuation(SimpleValuation&&) = default;
+            SimpleValuation& operator=(SimpleValuation const&) = default;
+            SimpleValuation& operator=(SimpleValuation&&) = default;
+            
+            void setIdentifierIndex(std::string const& name, uint_fast64_t index);
+            
+            virtual bool getBooleanValue(std::string const& name) const override;
+            virtual int_fast64_t getIntegerValue(std::string const& name) const override;
+            virtual double getDoubleValue(std::string const& name) const override;
+            
+        private:
+            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap;
+            std::vector<bool> booleanValues;
+            std::vector<int_fast64_t> integerValues;
+            std::vector<double> doubleValues;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_SIMPLEVALUATION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
new file mode 100644
index 000000000..c2d0b01cb
--- /dev/null
+++ b/src/storage/expressions/Valuation.h
@@ -0,0 +1,15 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_VALUATION_H_
+#define STORM_STORAGE_EXPRESSIONS_VALUATION_H_
+
+namespace storm {
+    namespace expressions {
+        class Valuation {
+        public:
+            virtual bool getBooleanValue(std::string const& name) const = 0;
+            virtual int_fast64_t getIntegerValue(std::string const& name) const = 0;
+            virtual double getDoubleValue(std::string const& name) const = 0;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_VALUATION_H_ */
\ No newline at end of file
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
new file mode 100644
index 000000000..9d9307bea
--- /dev/null
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -0,0 +1,9 @@
+#include "gtest/gtest.h"
+
+#include <map>
+
+#include "src/storage/expressions/SimpleValuation.h"
+
+TEST(Expression, SimpleValuationTest) {
+    ASSERT_NO_THROW(storm::expressions::SimpleValuation evaluation(1, 1, 1));
+}
\ No newline at end of file

From 47b0f0b0681aba7c79c5b74d0e2912d01b3ada42 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 31 Mar 2014 22:20:21 +0200
Subject: [PATCH 052/147] Further (preliminary) work on expression classes.

Former-commit-id: 71b71d6d3b69baa609a4260630a0e6bc22181cc9
---
 src/storage/expressions/BaseExpression.h      | 11 +++++---
 src/storage/expressions/Expression.cpp        | 20 +++++++++++--
 src/storage/expressions/Expression.h          | 28 +++++++++++++------
 src/storage/expressions/ExpressionVisitor.h   | 12 ++++++++
 src/storage/expressions/SimpleValuation.cpp   | 21 ++++++++++++--
 src/storage/expressions/SimpleValuation.h     |  4 +++
 src/storage/expressions/SubstitutionVisitor.h | 17 +++++++++++
 7 files changed, 95 insertions(+), 18 deletions(-)
 create mode 100644 src/storage/expressions/ExpressionVisitor.h
 create mode 100644 src/storage/expressions/SubstitutionVisitor.h

diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 85b521726..54102464e 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
 
 #include "src/storage/expressions/Valuation.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
 
 namespace storm {
     namespace expressions {
@@ -12,13 +13,15 @@ namespace storm {
              */
             enum ReturnType {undefined, bool_, int_, double_};
             
-            std::unique_ptr<BaseExpression> substitute() const = 0;
+            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0;
             
-            virtual int_fast64_t evaluateAsInt(Evaluation const& evaluation) const = 0;
+            virtual bool evaluateAsBool(Valuation const& evaluation) const = 0;
             
-            virtual bool evaluateAsBool(Evaluation const& evaluation) const = 0;
+            virtual double evaluateAsDouble(Valuation const& evaluation) const = 0;
             
-            virtual double evaluateAsDouble(Evaluation const& evaluation) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator+(BaseExpression const& other) const = 0;
+            
+            virtual void visit(ExpressionVisitor* visitor) const = 0;
         };
     }
 }
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 335fa3ca7..7ca4e23bf 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -1,13 +1,29 @@
+#include <map>
+#include <unordered_map>
+
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace expressions {
-        virtual Expression Expression::operator+(Expression const& other) {
+        Expression::Expression(std::unique_ptr<BaseExpression>&& expressionPtr) : expressionPtr(std::move(expressionPtr)) {
+            // Intentionally left empty.
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const {
+            SubstitutionVisitor visitor;
+            return visitor.substitute(this->getBaseExpression(), identifierToExpressionMap);
+        }
+
+        Expression Expression::operator+(Expression const& other) {
             return Expression(this->getBaseExpression() + other.getBaseExpression());
         }
         
-        BaseExpression const& getBaseExpression() const {
+        BaseExpression const& Expression::getBaseExpression() const {
             return *this->expressionPtr;
         }
+        
+        template Expression Expression::substitute<std::map>(std::map<std::string, storm::expressions::Expression> const&) const;
+        template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, storm::expressions::Expression> const&) const;
     }
 }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index c44219736..a780a0819 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -1,6 +1,10 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 
+#include <functional>
+
+#include "src/storage/expressions/BaseExpression.h"
+
 namespace storm {
     namespace expressions {
         class Expression {
@@ -12,19 +16,25 @@ namespace storm {
             virtual Expression operator+(Expression const& other);
             
             /*!
-             * Substitutes all occurrences of identifiers according to the given substitution. Note that this
-             * substitution is done simultaneously, i.e., identifiers appearing in the expressions that were "plugged
-             * in" are not substituted.
-             *
-             * @param substitutionFilter A function that returns true iff the given identifier is supposed to be
+             * Substitutes all occurrences of identifiers according to the given map. Note that this substitution is
+             * done simultaneously, i.e., identifiers appearing in the expressions that were "plugged in" are not
              * substituted.
-             * @param substitution A substitution that returns for each identifier an expression that is supposed to
-             * replace the identifier.
-             * @return An expression in which all identifiers
+             *
+             * @param identifierToExpressionMap A mapping from identifiers to the expression they are substituted with.
+             * @return An expression in which all identifiers in the key set of the mapping are replaced by the
+             * expression they are mapped to.
              */
-            Expression substitute(std::function<Expression (std::string const&)> const& substitution) const;
+            template<template<typename... Arguments> class MapType>
+            Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const;
             
         private:
+            /*!
+             * Creates an expression with the given underlying base expression.
+             *
+             * @param expressionPtr A pointer to the underlying base expression.
+             */
+            Expression(std::unique_ptr<BaseExpression>&& expressionPtr);
+            
             /*!
              * Retrieves the base expression underlying this expression object. Note that prior to calling this, the
              * expression object must be properly initialized.
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
new file mode 100644
index 000000000..e145826b6
--- /dev/null
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -0,0 +1,12 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
+
+namespace storm {
+    namespace expressions {
+        class ExpressionVisitor {
+            
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index 20c9f9f2f..ea829557e 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -14,16 +14,31 @@ namespace storm {
             (*this->identifierToIndexMap)[name] = index;
         }
         
+        void SimpleValuation::setBooleanValue(std::string const& name, bool value) {
+            this->booleanValues[(*this->identifierToIndexMap)[name]] = value;
+        }
+        
+        void SimpleValuation::setIntegerValue(std::string const& name, int_fast64_t value) {
+            this->integerValues[(*this->identifierToIndexMap)[name]] = value;
+        }
+        
+        void SimpleValuation::setDoubleValue(std::string const& name, double value) {
+            this->doubleValues[(*this->identifierToIndexMap)[name]] = value;
+        }
+        
         bool SimpleValuation::getBooleanValue(std::string const& name) const {
-            return false;
+            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            return this->booleanValues[nameIndexPair->second];
         }
         
         int_fast64_t SimpleValuation::getIntegerValue(std::string const& name) const {
-            return 0;
+            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            return this->integerValues[nameIndexPair->second];
         }
         
         double SimpleValuation::getDoubleValue(std::string const& name) const {
-            return 0.0;
+            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            return this->doubleValues[nameIndexPair->second];
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index fd7d3c8b0..399a6d7f4 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -24,6 +24,10 @@ namespace storm {
             
             void setIdentifierIndex(std::string const& name, uint_fast64_t index);
             
+            void setBooleanValue(std::string const& name, bool value);
+            void setIntegerValue(std::string const& name, int_fast64_t value);
+            void setDoubleValue(std::string const& name, double value);
+            
             virtual bool getBooleanValue(std::string const& name) const override;
             virtual int_fast64_t getIntegerValue(std::string const& name) const override;
             virtual double getDoubleValue(std::string const& name) const override;
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
new file mode 100644
index 000000000..217b07b23
--- /dev/null
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -0,0 +1,17 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+
+namespace storm {
+    namespace expressions {
+        class SubstitutionVisitor : public ExpressionVisitor {
+        public:
+            template<template<typename... Arguments> class MapType>
+            Expression substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap);
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_ */
\ No newline at end of file

From 1d6c25547b87a77d836a2d3574fa9ed020cfb5ce Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 1 Apr 2014 17:24:40 +0200
Subject: [PATCH 053/147] Further work on new expressions.

Former-commit-id: 1be5abbd68adf5b179c0e8a725edf1e3340988a7
---
 src/exceptions/ExceptionMacros.h              | 31 ++++++++++
 src/storage/expressions/BaseExpression.cpp    | 23 ++++++++
 src/storage/expressions/BaseExpression.h      | 43 ++++++++++++--
 src/storage/expressions/Expression.cpp        |  7 ++-
 src/storage/expressions/Expression.h          |  8 +++
 .../expressions/SubstitutionVisitor.cpp       | 17 ++++++
 src/storage/expressions/SubstitutionVisitor.h |  4 +-
 .../expressions/VariableExpression.cpp        | 56 +++++++++++++++++++
 src/storage/expressions/VariableExpression.h  | 47 ++++++++++++++++
 9 files changed, 228 insertions(+), 8 deletions(-)
 create mode 100644 src/exceptions/ExceptionMacros.h
 create mode 100644 src/storage/expressions/BaseExpression.cpp
 create mode 100644 src/storage/expressions/SubstitutionVisitor.cpp
 create mode 100644 src/storage/expressions/VariableExpression.cpp
 create mode 100644 src/storage/expressions/VariableExpression.h

diff --git a/src/exceptions/ExceptionMacros.h b/src/exceptions/ExceptionMacros.h
new file mode 100644
index 000000000..dabfe25cb
--- /dev/null
+++ b/src/exceptions/ExceptionMacros.h
@@ -0,0 +1,31 @@
+#ifndef STORM_EXCEPTIONS_EXCEPTIONMACROS_H_
+#define STORM_EXCEPTIONS_EXCEPTIONMACROS_H_
+
+#include <cassert>
+
+#include "log4cplus/logger.h"
+#include "log4cplus/loggingmacros.h"
+
+extern log4cplus::Logger logger;
+
+#ifndef NDEBUG
+#define LOG_ASSERT(cond, message)               \
+{                                               \
+    if (!(cond)) {                              \
+        LOG4CPLUS_ERROR(logger, message);       \
+        assert(cond);                           \
+    }                                           \
+} while (false)
+#define LOG_THROW(cond, exception, message)     \
+{                                               \
+    if (!(cond)) {                              \
+        LOG4CPLUS_ERROR(logger, message);       \
+        throw exception() << message;           \
+    }                                           \
+} while (false)
+#else
+#define LOG_ASSERT(cond, message) /* empty */
+#define LOG_THROW(cond, exception, message) /* empty */
+#endif
+
+#endif /* STORM_EXCEPTIONS_EXCEPTIONMACROS_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
new file mode 100644
index 000000000..8a80a3b71
--- /dev/null
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -0,0 +1,23 @@
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        BaseExpression::BaseExpression() : returnType(undefined) {
+            // Intentionally left empty.
+        }
+        
+        BaseExpression::BaseExpression(ExpressionReturnType returnType) : returnType(returnType) {
+            // Intentionally left empty.
+        }
+
+        ExpressionReturnType BaseExpression::getReturnType() const {
+            return this->returnType;
+        }
+        
+        void BaseExpression::checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const {
+            if (actualType != expectedType) {
+                throw storm::exceptions::InvalidArgumentException() << errorMessage;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 54102464e..0412e11f8 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -3,25 +3,56 @@
 
 #include "src/storage/expressions/Valuation.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
+#include "src/exceptions/InvalidArgumentException.h"
 
 namespace storm {
     namespace expressions {
+        /*!
+         * Each node in an expression tree has a uniquely defined type from this enum.
+         */
+        enum ExpressionReturnType {undefined, bool_, int_, double_};
+        
         class BaseExpression {
         public:
-            /*!
-             * Each node in an expression tree has a uniquely defined type from this enum.
-             */
-            enum ReturnType {undefined, bool_, int_, double_};
             
-            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0;
+            BaseExpression();
+            BaseExpression(ExpressionReturnType returnType);
+            virtual ~BaseExpression() = default;
             
-            virtual bool evaluateAsBool(Valuation const& evaluation) const = 0;
+            ExpressionReturnType getReturnType() const;
             
+            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0;
+            virtual bool evaluateAsBool(Valuation const& evaluation) const = 0;
             virtual double evaluateAsDouble(Valuation const& evaluation) const = 0;
             
             virtual std::unique_ptr<BaseExpression> operator+(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator-(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator-() const = 0;
+            virtual std::unique_ptr<BaseExpression> operator*(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator/(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator&(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator|(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator~() const = 0;
             
+            virtual std::unique_ptr<BaseExpression> equals(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> notEquals(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> greater(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> greaterOrEqual(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> less(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> lessOrEqual(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> minimum(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> maximum(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> mod(BaseExpression const& other) const = 0;
+            virtual std::unique_ptr<BaseExpression> floor() const = 0;
+            virtual std::unique_ptr<BaseExpression> ceil() const = 0;
+
             virtual void visit(ExpressionVisitor* visitor) const = 0;
+            
+        protected:
+            void checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const;
+            
+        private:
+            ExpressionReturnType returnType;
         };
     }
 }
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 7ca4e23bf..c73108336 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -2,6 +2,7 @@
 #include <unordered_map>
 
 #include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/SubstitutionVisitor.h"
 
 namespace storm {
     namespace expressions {
@@ -12,7 +13,7 @@ namespace storm {
         template<template<typename... Arguments> class MapType>
         Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const {
             SubstitutionVisitor visitor;
-            return visitor.substitute(this->getBaseExpression(), identifierToExpressionMap);
+            return visitor.substitute<MapType>(this->getBaseExpressionPointer(), identifierToExpressionMap);
         }
 
         Expression Expression::operator+(Expression const& other) {
@@ -23,6 +24,10 @@ namespace storm {
             return *this->expressionPtr;
         }
         
+        BaseExpression const* Expression::getBaseExpressionPointer() const {
+            return this->expressionPtr.get();
+        }
+        
         template Expression Expression::substitute<std::map>(std::map<std::string, storm::expressions::Expression> const&) const;
         template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, storm::expressions::Expression> const&) const;
     }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index a780a0819..9b2fe78c1 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -8,6 +8,7 @@
 namespace storm {
     namespace expressions {
         class Expression {
+        public:
             Expression() = default;
             
             // Static factory methods to create atomic expression parts.
@@ -43,6 +44,13 @@ namespace storm {
              */
             BaseExpression const& getBaseExpression() const;
             
+            /*!
+             * Retrieves a pointer to the base expression underlying this expression object.
+             *
+             * @return A pointer to the underlying base expression.
+             */
+            BaseExpression const* getBaseExpressionPointer() const;
+            
             // A pointer to the underlying base expression.
             std::unique_ptr<BaseExpression> expressionPtr;
         };
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
new file mode 100644
index 000000000..8c478d682
--- /dev/null
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -0,0 +1,17 @@
+#include <map>
+#include <unordered_map>
+
+#include "src/storage/expressions/SubstitutionVisitor.h"
+
+namespace storm {
+    namespace expressions  {
+        template<template<typename... Arguments> class MapType>
+        Expression SubstitutionVisitor::substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap) {
+            return Expression();
+        }
+        
+        // Explicitly instantiate substitute with map and unordered_map.
+        template Expression SubstitutionVisitor::substitute<std::map>(BaseExpression const* expression, std::map<std::string, Expression> const& identifierToExpressionMap);
+        template Expression SubstitutionVisitor::substitute<std::unordered_map>(BaseExpression const* expression, std::unordered_map<std::string, Expression> const& identifierToExpressionMap);
+    }
+}
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index 217b07b23..f65482e3c 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -1,7 +1,7 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
 #define STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
 
-#include "src/storage/expressions/BaseExpression.h"
+#include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 
 namespace storm {
@@ -10,6 +10,8 @@ namespace storm {
         public:
             template<template<typename... Arguments> class MapType>
             Expression substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap);
+            
+            
         };
     }
 }
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
new file mode 100644
index 000000000..bce5ec0dc
--- /dev/null
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -0,0 +1,56 @@
+#include "src/storage/expressions/VariableExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
+
+namespace storm {
+    namespace expressions {
+        VariableExpression::VariableExpression(ExpressionReturnType returnType, std::string const& variableName) : BaseExpression(returnType), variableName(variableName) {
+            // Intentionally left empty.
+        }
+        
+        std::string const& VariableExpression::getVariableName() const {
+            return this->variableName;
+        }
+        
+        int_fast64_t VariableExpression::evaluateAsInt(Valuation const& evaluation) const {
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::int_), "Cannot evaluate expression as integer: return type is not an integer.");
+            return evaluation.getIntegerValue(this->getVariableName());
+        }
+        
+        bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const {
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not an integer.");
+            return evaluation.getBooleanValue(this->getVariableName());
+        }
+        
+        double VariableExpression::evaluateAsDouble(Valuation const& evaluation) const {
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::double_), "Cannot evaluate expression as integer: return type is not an integer.");
+            return evaluation.getDoubleValue(this->getVariableName());
+        }
+        
+        std::unique_ptr<BaseExpression> VariableExpression::operator+(BaseExpression const& other) const {
+            // FIXME
+            return nullptr;
+        }
+        
+        std::unique_ptr<BaseExpression> operator-(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> operator-() const;
+        std::unique_ptr<BaseExpression> operator*(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> operator/(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> operator&(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> operator|(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> operator~() const;
+        
+        std::unique_ptr<BaseExpression> equals(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> notEquals(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> greater(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> greaterOrEqual(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> less(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> lessOrEqual(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> minimum(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> maximum(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> mod(BaseExpression const& other) const;
+        std::unique_ptr<BaseExpression> floor() const;
+        std::unique_ptr<BaseExpression> ceil() const;
+        
+        void visit(ExpressionVisitor* visitor) const;
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
new file mode 100644
index 000000000..2a5381a53
--- /dev/null
+++ b/src/storage/expressions/VariableExpression.h
@@ -0,0 +1,47 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class VariableExpression : public BaseExpression {
+            VariableExpression(ExpressionReturnType returnType, std::string const& variableName);
+            virtual ~VariableExpression() = default;
+            
+            std::string const& getVariableName() const;
+            
+            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const;
+            virtual bool evaluateAsBool(Valuation const& evaluation) const;
+            virtual double evaluateAsDouble(Valuation const& evaluation) const;
+            
+            virtual std::unique_ptr<BaseExpression> operator+(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> operator-(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> operator-() const;
+            virtual std::unique_ptr<BaseExpression> operator*(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> operator/(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> operator&(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> operator|(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> operator~() const;
+            
+            virtual std::unique_ptr<BaseExpression> equals(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> notEquals(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> greater(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> greaterOrEqual(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> less(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> lessOrEqual(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> minimum(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> maximum(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> mod(BaseExpression const& other) const;
+            virtual std::unique_ptr<BaseExpression> floor() const;
+            virtual std::unique_ptr<BaseExpression> ceil() const;
+            
+            virtual void visit(ExpressionVisitor* visitor) const;
+            
+        private:
+            std::string variableName;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_ */
\ No newline at end of file

From c8b5897cff63f1030d2b9f1281f79c59af463ebc Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 2 Apr 2014 23:31:41 +0200
Subject: [PATCH 054/147] Designed interface of expression classes and started
 implementing it.

Former-commit-id: 67ac2a1764c45891c83e9bd1b9e63883aefa1bdc
---
 src/storage/expressions/BaseExpression.cpp    |  29 ++--
 src/storage/expressions/BaseExpression.h      | 139 ++++++++++++++----
 .../BinaryBooleanFunctionExpression.cpp       |  73 +++++++++
 .../BinaryBooleanFunctionExpression.h         |  54 +++++++
 src/storage/expressions/BinaryExpression.cpp  |  47 ++++++
 src/storage/expressions/BinaryExpression.h    |  60 ++++++++
 .../BinaryNumericalFunctionExpression.cpp     |  64 ++++++++
 .../BinaryNumericalFunctionExpression.h       |  55 +++++++
 .../expressions/BinaryRelationExpression.cpp  |  50 +++++++
 .../expressions/BinaryRelationExpression.h    |  54 +++++++
 .../expressions/BooleanConstantExpression.cpp |   9 ++
 .../expressions/BooleanConstantExpression.h   |  16 ++
 .../expressions/ConstantExpression.cpp        |  13 ++
 src/storage/expressions/ConstantExpression.h  |  20 +++
 .../expressions/DoubleConstantExpression.cpp  |   9 ++
 .../expressions/DoubleConstantExpression.h    |  16 ++
 src/storage/expressions/Expression.h          |  28 +++-
 src/storage/expressions/ExpressionVisitor.h   |   8 +-
 .../expressions/IntegerConstantExpression.cpp |   9 ++
 .../expressions/IntegerConstantExpression.h   |  15 ++
 .../UnaryBooleanFunctionExpression.cpp        |   9 ++
 .../UnaryBooleanFunctionExpression.h          |  21 +++
 src/storage/expressions/UnaryExpression.cpp   |   9 ++
 src/storage/expressions/UnaryExpression.h     |  18 +++
 .../UnaryNumericalFunctionExpression.cpp      |   9 ++
 .../UnaryNumericalFunctionExpression.h        |  21 +++
 src/storage/expressions/Valuation.h           |   2 +
 .../expressions/VariableExpression.cpp        |   6 +-
 src/storage/expressions/VariableExpression.h  |   2 +
 29 files changed, 822 insertions(+), 43 deletions(-)
 create mode 100644 src/storage/expressions/BinaryBooleanFunctionExpression.cpp
 create mode 100644 src/storage/expressions/BinaryBooleanFunctionExpression.h
 create mode 100644 src/storage/expressions/BinaryExpression.cpp
 create mode 100644 src/storage/expressions/BinaryExpression.h
 create mode 100644 src/storage/expressions/BinaryNumericalFunctionExpression.cpp
 create mode 100644 src/storage/expressions/BinaryNumericalFunctionExpression.h
 create mode 100644 src/storage/expressions/BinaryRelationExpression.cpp
 create mode 100644 src/storage/expressions/BinaryRelationExpression.h
 create mode 100644 src/storage/expressions/BooleanConstantExpression.cpp
 create mode 100644 src/storage/expressions/BooleanConstantExpression.h
 create mode 100644 src/storage/expressions/ConstantExpression.cpp
 create mode 100644 src/storage/expressions/ConstantExpression.h
 create mode 100644 src/storage/expressions/DoubleConstantExpression.cpp
 create mode 100644 src/storage/expressions/DoubleConstantExpression.h
 create mode 100644 src/storage/expressions/IntegerConstantExpression.cpp
 create mode 100644 src/storage/expressions/IntegerConstantExpression.h
 create mode 100644 src/storage/expressions/UnaryBooleanFunctionExpression.cpp
 create mode 100644 src/storage/expressions/UnaryBooleanFunctionExpression.h
 create mode 100644 src/storage/expressions/UnaryExpression.cpp
 create mode 100644 src/storage/expressions/UnaryExpression.h
 create mode 100644 src/storage/expressions/UnaryNumericalFunctionExpression.cpp
 create mode 100644 src/storage/expressions/UnaryNumericalFunctionExpression.h

diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index 8a80a3b71..550e2209f 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -1,11 +1,8 @@
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
-    namespace expressions {
-        BaseExpression::BaseExpression() : returnType(undefined) {
-            // Intentionally left empty.
-        }
-        
+    namespace expressions {        
         BaseExpression::BaseExpression(ExpressionReturnType returnType) : returnType(returnType) {
             // Intentionally left empty.
         }
@@ -14,10 +11,24 @@ namespace storm {
             return this->returnType;
         }
         
-        void BaseExpression::checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const {
-            if (actualType != expectedType) {
-                throw storm::exceptions::InvalidArgumentException() << errorMessage;
-            }
+        int_fast64_t BaseExpression::evaluateAsInt(Valuation const& evaluation) const {
+            LOG_ASSERT(false, "Unable to evaluate expression as integer.");
+        }
+        
+        bool BaseExpression::evaluateAsBool(Valuation const& evaluation) const {
+            LOG_ASSERT(false, "Unable to evaluate expression as boolean.");
+        }
+        
+        double BaseExpression::evaluateAsDouble(Valuation const& evaluation) const {
+            LOG_ASSERT(false, "Unable to evaluate expression as double.");
+        }
+        
+        bool BaseExpression::isTrue() const {
+            return false;
+        }
+
+        bool BaseExpression::isFalse() const {
+            return false;
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 0412e11f8..545289b08 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -1,6 +1,9 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
 
+#include <memory>
+#include <set>
+
 #include "src/storage/expressions/Valuation.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 #include "src/exceptions/InvalidArgumentException.h"
@@ -12,46 +15,122 @@ namespace storm {
          */
         enum ExpressionReturnType {undefined, bool_, int_, double_};
         
+        /*!
+         * The base class of all expression classes.
+         */
         class BaseExpression {
         public:
-            
-            BaseExpression();
+            /*!
+             * Constructs a base expression with the given return type.
+             *
+             * @param returnType The return type of the expression.
+             */
             BaseExpression(ExpressionReturnType returnType);
+            
+            // Create default versions of constructors and assignments.
+            BaseExpression(BaseExpression const&) = default;
+            BaseExpression(BaseExpression&&) = default;
+            BaseExpression& operator=(BaseExpression const&) = default;
+            BaseExpression& operator=(BaseExpression&&) = default;
+            
+            // Make the destructor virtual (to allow destruction via base class pointer) and default it.
             virtual ~BaseExpression() = default;
             
-            ExpressionReturnType getReturnType() const;
+            /*!
+             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
+             * valuation and returns the resulting boolean value. If the return type of the expression is not a boolean
+             * an exception is thrown.
+             *
+             * @param valuation The valuation of unknowns under which to evaluate the expression.
+             * @return The boolean value of the expression under the given valuation.
+             */
+            virtual bool evaluateAsBool(Valuation const& valuation) const;
+
+            /*!
+             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
+             * valuation and returns the resulting integer value. If the return type of the expression is not an integer
+             * an exception is thrown.
+             *
+             * @param valuation The valuation of unknowns under which to evaluate the expression.
+             * @return The integer value of the expression under the given valuation.
+             */
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const;
             
-            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0;
-            virtual bool evaluateAsBool(Valuation const& evaluation) const = 0;
-            virtual double evaluateAsDouble(Valuation const& evaluation) const = 0;
-            
-            virtual std::unique_ptr<BaseExpression> operator+(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> operator-(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> operator-() const = 0;
-            virtual std::unique_ptr<BaseExpression> operator*(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> operator/(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> operator&(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> operator|(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> operator~() const = 0;
-            
-            virtual std::unique_ptr<BaseExpression> equals(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> notEquals(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> greater(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> greaterOrEqual(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> less(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> lessOrEqual(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> minimum(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> maximum(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> mod(BaseExpression const& other) const = 0;
-            virtual std::unique_ptr<BaseExpression> floor() const = 0;
-            virtual std::unique_ptr<BaseExpression> ceil() const = 0;
+            /*!
+             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
+             * valuation and returns the resulting double value. If the return type of the expression is not a double
+             * an exception is thrown.
+             *
+             * @param valuation The valuation of unknowns under which to evaluate the expression.
+             * @return The double value of the expression under the given valuation.
+             */
+            virtual double evaluateAsDouble(Valuation const& valuation) const;
 
-            virtual void visit(ExpressionVisitor* visitor) const = 0;
+            /*!
+             * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants.
+             *
+             * @return True iff the expression is constant.
+             */
+            virtual bool isConstant() const = 0;
             
-        protected:
-            void checkType(ExpressionReturnType actualType, ExpressionReturnType expectedType, std::string const& errorMessage) const;
+            /*!
+             * Checks if the expression is equal to the boolean literal true.
+             *
+             * @return True iff the expression is equal to the boolean literal true.
+             */
+            virtual bool isTrue() const;
+            
+            /*!
+             * Checks if the expression is equal to the boolean literal false.
+             *
+             * @return True iff the expression is equal to the boolean literal false.
+             */
+            virtual bool isFalse() const;
+            
+            /*!
+             * Retrieves the set of all variables that appear in the expression.
+             *
+             * @return The set of all variables that appear in the expression.
+             */
+            virtual std::set<std::string> getVariables() const = 0;
+            
+            /*!
+             * Retrieves the set of all constants that appear in the expression.
+             *
+             * @return The set of all constants that appear in the expression.
+             */
+            virtual std::set<std::string> getConstants() const = 0;
+            
+            /*!
+             * Simplifies the expression according to some simple rules.
+             *
+             * @return A pointer to the simplified expression.
+             */
+            virtual std::unique_ptr<BaseExpression> simplify() const = 0;
+            
+            /*!
+             * Accepts the given visitor by calling its visit method.
+             *
+             * @param visitor The visitor that is to be accepted.
+             */
+            virtual void accept(ExpressionVisitor* visitor) const = 0;
+            
+            /*!
+             * Performs a deep-copy of the expression.
+             *
+             * @return A pointer to a deep-copy of the expression.
+             */
+            virtual std::unique_ptr<BaseExpression> clone() const = 0;
+            
+            /*!
+             * Retrieves the return type of the expression.
+             *
+             * @return The return type of the expression.
+             */
+            ExpressionReturnType getReturnType() const;
             
         private:
+            // The return type of this expression.
             ExpressionReturnType returnType;
         };
     }
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
new file mode 100644
index 000000000..749b1d1e1
--- /dev/null
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -0,0 +1,73 @@
+#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
+
+namespace storm {
+    namespace expressions {
+        BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), operatorType(operatorType) {
+            // Intentionally left empty.
+        }
+        
+        BinaryBooleanFunctionExpression::OperatorType BinaryBooleanFunctionExpression::getOperatorType() const {
+            return this->operatorType;
+        }
+        
+        BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other) : BinaryExpression(other), operatorType(other.getOperatorType()) {
+            // Intentionally left empty.
+        }
+        
+        BinaryBooleanFunctionExpression& BinaryBooleanFunctionExpression::operator=(BinaryBooleanFunctionExpression const& other) {
+            if (this != &other) {
+                BinaryExpression::operator=(other);
+                this->operatorType = other.getOperatorType();
+            }
+            return *this;
+        }
+        
+        bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
+            bool firstOperandEvaluation = this->getFirstOperand()->evaluateAsBool(valuation);
+            bool secondOperandEvaluation = this->getSecondOperand()->evaluateAsBool(valuation);
+            
+            bool result;
+            switch (this->getOperatorType()) {
+                case AND: result = firstOperandEvaluation && secondOperandEvaluation; break;
+                case OR: result = firstOperandEvaluation || secondOperandEvaluation; break;
+            }
+            
+            return result;
+        }
+        
+        std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::simplify() const {
+            std::unique_ptr<BaseExpression> firstOperandSimplified = this->getFirstOperand()->simplify();
+            std::unique_ptr<BaseExpression> secondOperandSimplified = this->getSecondOperand()->simplify();
+            
+            switch (this->getOperatorType()) {
+                case AND: if (firstOperandSimplified->isTrue()) {
+                    return secondOperandSimplified;
+                } else if (firstOperandSimplified->isFalse()) {
+                    return firstOperandSimplified;
+                } else if (secondOperandSimplified->isTrue()) {
+                    return firstOperandSimplified;
+                } else if (secondOperandSimplified->isFalse()) {
+                    return secondOperandSimplified;
+                }
+                break;
+                case OR: if (firstOperandSimplified->isTrue()) {
+                    return firstOperandSimplified;
+                } else if (firstOperandSimplified->isFalse()) {
+                    return secondOperandSimplified;
+                } else if (secondOperandSimplified->isTrue()) {
+                    return secondOperandSimplified;
+                } else if (secondOperandSimplified->isFalse()) {
+                    return firstOperandSimplified;
+                }
+            }
+            
+            return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getReturnType(), std::move(firstOperandSimplified), std::move(secondOperandSimplified), this->getOperatorType()));
+        }
+        
+        void BinaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        virtual std::unique_ptr<BaseExpression> clone() const override;
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
new file mode 100644
index 000000000..f476550d0
--- /dev/null
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -0,0 +1,54 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
+
+#include "src/storage/expressions/BinaryExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class BinaryBooleanFunctionExpression : public BinaryExpression {
+        public:
+            /*!
+             * An enum type specifying the different operators applicable.
+             */
+            enum OperatorType {AND, OR};
+            
+            /*!
+             * Creates a binary boolean function expression with the given return type, operands and operator.
+             *
+             * @param returnType The return type of the expression.
+             * @param firstOperand The first operand of the expression.
+             * @param secondOperand The second operand of the expression.
+             * @param functionType The operator of the expression.
+             */
+            BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& fistOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType);
+            
+            // Provide custom versions of copy construction and assignment.
+            BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other);
+            BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression const& other);
+            
+            // Create default variants of move construction/assignment and virtual destructor.
+            BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression&&) = default;
+            BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression&&) = default;
+            virtual ~BinaryBooleanFunctionExpression() = default;
+            
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the operator associated with the expression.
+             *
+             * @return The operator associated with the expression.
+             */
+            OperatorType getOperatorType() const;
+            
+        private:
+            // The operator of the expression.
+            OperatorType operatorType;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryExpression.cpp b/src/storage/expressions/BinaryExpression.cpp
new file mode 100644
index 000000000..9038aca41
--- /dev/null
+++ b/src/storage/expressions/BinaryExpression.cpp
@@ -0,0 +1,47 @@
+#include "src/storage/expressions/BinaryExpression.h"
+
+namespace storm {
+    namespace expressions {
+        BinaryExpression::BinaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand) : BaseExpression(returnType), firstOperand(std::move(firstOperand)), secondOperand(std::move(secondOperand)) {
+            // Intentionally left empty.
+        }
+        
+        BinaryExpression::BinaryExpression(BinaryExpression const& other) : BaseExpression(other.getReturnType()), firstOperand(other.getFirstOperand()->clone()), secondOperand(other.getSecondOperand()->clone()) {
+            // Intentionally left empty.
+        }
+        
+        BinaryExpression& BinaryExpression::operator=(BinaryExpression const& other) {
+            if (this != &other) {
+                this->firstOperand = other.getFirstOperand()->clone();
+                this->secondOperand = other.getSecondOperand()->clone();
+            }
+            return *this;
+        }
+        
+        bool BinaryExpression::isConstant() const {
+            return this->getFirstOperand()->isConstant() && this->getSecondOperand()->isConstant();
+        }
+        
+        std::set<std::string> BinaryExpression::getVariables() const {
+            std::set<std::string> firstVariableSet = this->getFirstOperand()->getVariables();
+            std::set<std::string> secondVariableSet = this->getSecondOperand()->getVariables();
+            firstVariableSet.insert(secondVariableSet.begin(), secondVariableSet.end());
+            return firstVariableSet;
+        }
+        
+        std::set<std::string> BinaryExpression::getConstants() const {
+            std::set<std::string> firstConstantSet = this->getFirstOperand()->getVariables();
+            std::set<std::string> secondConstantSet = this->getSecondOperand()->getVariables();
+            firstConstantSet.insert(secondConstantSet.begin(), secondConstantSet.end());
+            return firstConstantSet;
+        }
+        
+        std::unique_ptr<BaseExpression> const& BinaryExpression::getFirstOperand() const {
+            return this->firstOperand;
+        }
+        
+        std::unique_ptr<BaseExpression> const& BinaryExpression::getSecondOperand() const {
+            return this->secondOperand;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h
new file mode 100644
index 000000000..a94513cb5
--- /dev/null
+++ b/src/storage/expressions/BinaryExpression.h
@@ -0,0 +1,60 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        /*!
+         * The base class of all binary expressions.
+         */
+        class BinaryExpression : public BaseExpression {
+        public:
+            /*!
+             * Constructs a binary expression with the given return type and operands.
+             *
+             * @param returnType The return type of the expression.
+             * @param firstOperand The first operand of the expression.
+             * @param secondOperand The second operand of the expression.
+             */
+            BinaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand);
+            
+            // Provide custom versions of copy construction and assignment.
+            BinaryExpression(BinaryExpression const& other);
+            BinaryExpression& operator=(BinaryExpression const& other);
+
+            // Create default variants of move construction/assignment and virtual destructor.
+            BinaryExpression(BinaryExpression&&) = default;
+            BinaryExpression& operator=(BinaryExpression&&) = default;
+            virtual ~BinaryExpression() = default;
+
+            // Override base class methods.
+            virtual bool isConstant() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            
+            /*!
+             * Retrieves the first operand of the expression.
+             *
+             * @return The first operand of the expression.
+             */
+            std::unique_ptr<BaseExpression> const& getFirstOperand() const;
+            
+            /*!
+             * Retrieves the second operand of the expression.
+             *
+             * @return The second operand of the expression.
+             */
+            std::unique_ptr<BaseExpression> const& getSecondOperand() const;
+
+        private:
+            // The first operand of the expression.
+            std::unique_ptr<BaseExpression> firstOperand;
+            
+            // The second operand of the expression.
+            std::unique_ptr<BaseExpression> secondOperand;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
new file mode 100644
index 000000000..61e491650
--- /dev/null
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -0,0 +1,64 @@
+#include <algorithm>
+
+#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
+
+namespace storm {
+    namespace expressions {
+        BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), operatorType(operatorType) {
+            // Intentionally left empty.
+        }
+        
+        BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other) : BinaryExpression(other), operatorType(this->getOperatorType()) {
+            // Intentionally left empty.
+        }
+        
+        BinaryNumericalFunctionExpression& BinaryNumericalFunctionExpression::operator=(BinaryNumericalFunctionExpression const& other) {
+            if (this != &other) {
+                BinaryExpression::operator=(other);
+                this->operatorType = other.getOperatorType();
+            }
+            return *this;
+        }
+        
+        int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
+            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::int_, "Unable to evaluate expression as integer.");
+            int_fast64_t firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation);
+            int_fast64_t secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation);
+            switch (this->getOperatorType()) {
+                case PLUS: return firstOperandEvaluation + secondOperandEvaluation; break;
+                case MINUS: return firstOperandEvaluation - secondOperandEvaluation; break;
+                case TIMES: return firstOperandEvaluation * secondOperandEvaluation; break;
+                case DIVIDE: return firstOperandEvaluation / secondOperandEvaluation; break;
+                case MIN: return std::min(firstOperandEvaluation, secondOperandEvaluation); break;
+                case MAX: return std::max(firstOperandEvaluation, secondOperandEvaluation); break;
+            }
+        }
+        
+        double BinaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
+            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::int_, "Unable to evaluate expression as integer.");
+            double firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation);
+            double secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation);
+            switch (this->getOperatorType()) {
+                case PLUS: return firstOperandEvaluation + secondOperandEvaluation; break;
+                case MINUS: return firstOperandEvaluation - secondOperandEvaluation; break;
+                case TIMES: return firstOperandEvaluation * secondOperandEvaluation; break;
+                case DIVIDE: return firstOperandEvaluation / secondOperandEvaluation; break;
+                case MIN: return std::min(firstOperandEvaluation, secondOperandEvaluation); break;
+                case MAX: return std::max(firstOperandEvaluation, secondOperandEvaluation); break;
+            }
+        }
+        
+        std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::simplify() const {
+            return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType(), this->getFirstOperand()->simplify(), this->getSecondOperand()->simplify(), this->getOperatorType()));
+        }
+        
+        void BinaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(*this));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
new file mode 100644
index 000000000..56ae3b55d
--- /dev/null
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -0,0 +1,55 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_
+
+#include "src/storage/expressions/BinaryExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class BinaryNumericalFunctionExpression : public BinaryExpression {
+        public:
+            /*!
+             * An enum type specifying the different operators applicable.
+             */
+            enum OperatorType {PLUS, MINUS, TIMES, DIVIDE, MIN, MAX};
+            
+            /*!
+             * Constructs a binary numerical function expression with the given return type, operands and operator.
+             *
+             * @param returnType The return type of the expression.
+             * @param firstOperand The first operand of the expression.
+             * @param secondOperand The second operand of the expression.
+             * @param functionType The operator of the expression.
+             */
+            BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType);
+            
+            // Provide custom versions of copy construction and assignment.
+            BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other);
+            BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression const& other);
+            
+            // Create default variants of move construction/assignment and virtual destructor.
+            BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression&&) = default;
+            BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression&&) = default;
+            virtual ~BinaryNumericalFunctionExpression() = default;
+            
+            // Override base class methods.
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the operator associated with the expression.
+             *
+             * @return The operator associated with the expression.
+             */
+            OperatorType getOperatorType() const;
+            
+        private:
+            // The operator of the expression.
+            OperatorType operatorType;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp
new file mode 100644
index 000000000..a203ec2fb
--- /dev/null
+++ b/src/storage/expressions/BinaryRelationExpression.cpp
@@ -0,0 +1,50 @@
+#include "src/storage/expressions/BinaryRelationExpression.h"
+
+namespace storm {
+    namespace expressions {
+        BinaryRelationExpression::BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, RelationType relationType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), relationType(relationType) {
+            // Intentionally left empty.
+        }
+        
+        BinaryRelationExpression::BinaryRelationExpression(BinaryRelationExpression const& other) : BinaryExpression(other), relationType(other.getRelationType()) {
+            // Intentionally left empty.
+        }
+        
+        BinaryRelationExpression& BinaryRelationExpression::operator=(BinaryRelationExpression const& other) {
+            if (this != &other) {
+                BinaryExpression::operator=(other);
+                this->relationType = other.getRelationType();
+            }
+            return *this;
+        }
+        
+        bool BinaryRelationExpression::evaluateAsBool(Valuation const& valuation) const {
+            double firstOperandEvaluated = this->getFirstOperand()->evaluateAsDouble(valuation);
+            double secondOperandEvaluated = this->getSecondOperand()->evaluateAsDouble(valuation);
+            switch (this->getRelationType()) {
+                case EQUAL: return firstOperandEvaluated == secondOperandEvaluated; break;
+                case NOT_EQUAL: return firstOperandEvaluated != secondOperandEvaluated; break;
+                case GREATER: return firstOperandEvaluated > secondOperandEvaluated; break;
+                case GREATER_OR_EQUAL: return firstOperandEvaluated >= secondOperandEvaluated; break;
+                case LESS: return firstOperandEvaluated < secondOperandEvaluated; break;
+                case LESS_OR_EQUAL: return firstOperandEvaluated <= secondOperandEvaluated; break;
+            }
+        }
+        
+        std::unique_ptr<BaseExpression> BinaryRelationExpression::simplify() const {
+            return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(this->getReturnType(), this->getFirstOperand()->simplify(), this->getSecondOperand()->simplify(), this->getRelationType()));
+        }
+        
+        void BinaryRelationExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> BinaryRelationExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(*this));
+        }
+        
+        BinaryRelationExpression::RelationType BinaryRelationExpression::getRelationType() const {
+            return this->relationType;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h
new file mode 100644
index 000000000..7b45cc1c1
--- /dev/null
+++ b/src/storage/expressions/BinaryRelationExpression.h
@@ -0,0 +1,54 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
+
+#include "src/storage/expressions/BinaryExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class BinaryRelationExpression : public BinaryExpression {
+        public:
+            /*!
+             * An enum type specifying the different relations applicable.
+             */
+            enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL};
+            
+            /*!
+             * Creates a binary relation expression with the given return type, operands and relation type.
+             *
+             * @param returnType The return type of the expression.
+             * @param firstOperand The first operand of the expression.
+             * @param secondOperand The second operand of the expression.
+             * @param relationType The operator of the expression.
+             */
+            BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, RelationType relationType);
+            
+            // Provide custom versions of copy construction and assignment.
+            BinaryRelationExpression(BinaryRelationExpression const& other);
+            BinaryRelationExpression& operator=(BinaryRelationExpression const& other);
+            
+            // Create default variants of move construction/assignment and virtual destructor.
+            BinaryRelationExpression(BinaryRelationExpression&&) = default;
+            BinaryRelationExpression& operator=(BinaryRelationExpression&&) = default;
+            virtual ~BinaryRelationExpression() = default;
+            
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the relation associated with the expression.
+             *
+             * @return The relation associated with the expression.
+             */
+            RelationType getRelationType() const;
+            
+        private:
+            // The relation type of the expression.
+            RelationType relationType;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp
new file mode 100644
index 000000000..8c40b02af
--- /dev/null
+++ b/src/storage/expressions/BooleanConstantExpression.cpp
@@ -0,0 +1,9 @@
+#include "src/storage/expressions/BooleanConstantExpression.h"
+
+namespace storm {
+    namespace expressions {
+        BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::bool_, constantName) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
new file mode 100644
index 000000000..c337f01c0
--- /dev/null
+++ b/src/storage/expressions/BooleanConstantExpression.h
@@ -0,0 +1,16 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
+
+#include "src/storage/expressions/ConstantExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class BooleanConstantExpression : public ConstantExpression {
+        public:
+            BooleanConstantExpression(std::string const& constantName);
+            virtual ~BooleanConstantExpression() = default;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp
new file mode 100644
index 000000000..d6cbce747
--- /dev/null
+++ b/src/storage/expressions/ConstantExpression.cpp
@@ -0,0 +1,13 @@
+#include "src/storage/expressions/ConstantExpression.h"
+
+namespace storm {
+    namespace expressions {
+        ConstantExpression::ConstantExpression(ReturnType returnType, std::string const& constantName) : BaseExpression(returnType), constantName(constantName) {
+            // Intentionally left empty.
+        }
+        
+        std::string const& ConstantExpression::getConstantName() const {
+            return this->constantName;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
new file mode 100644
index 000000000..08fb80321
--- /dev/null
+++ b/src/storage/expressions/ConstantExpression.h
@@ -0,0 +1,20 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class ConstantExpression : public BaseExpression {
+            ConstantExpression(ExpressionReturnType returnType, std::string const& constantName);
+            virtual ~ConstantExpression() = default;
+            
+            std::string const& getConstantName() const;
+            
+        private:
+            std::string constantName;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/DoubleConstantExpression.cpp b/src/storage/expressions/DoubleConstantExpression.cpp
new file mode 100644
index 000000000..25fa035d4
--- /dev/null
+++ b/src/storage/expressions/DoubleConstantExpression.cpp
@@ -0,0 +1,9 @@
+#include "src/storage/expressions/DoubleConstantExpression.h"
+
+namespace storm {
+    namespace expressions {
+        DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::double_, constantName) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h
new file mode 100644
index 000000000..fc5725642
--- /dev/null
+++ b/src/storage/expressions/DoubleConstantExpression.h
@@ -0,0 +1,16 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
+
+#include "src/storage/expressions/ConstantExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class DoubleConstantExpression : public ConstantExpression {
+        public:
+            DoubleConstantExpression(std::string const& constantName);
+            virtual ~DoubleConstantExpression() = default;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 9b2fe78c1..c866d64cb 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -14,7 +14,26 @@ namespace storm {
             // Static factory methods to create atomic expression parts.
             
             // Virtual operator overloading.
-            virtual Expression operator+(Expression const& other);
+            Expression operator+(Expression const& other) const;
+            Expression operator-(Expression const& other) const;
+            Expression operator-() const;
+            Expression operator*(Expression const& other) const;
+            Expression operator/(Expression const& other) const;
+            Expression operator&(Expression const& other) const;
+            Expression operator|(Expression const& other) const;
+            Expression operator~() const;
+            
+            Expression equals(Expression const& other) const;
+            Expression notEquals(Expression const& other) const;
+            Expression greater(Expression const& other) const;
+            Expression greaterOrEqual(Expression const& other) const;
+            Expression less(Expression const& other) const;
+            Expression lessOrEqual(Expression const& other) const;
+            Expression minimum(Expression const& other) const;
+            Expression maximum(Expression const& other) const;
+            Expression mod(Expression const& other) const;
+            Expression floor() const;
+            Expression ceil() const;
             
             /*!
              * Substitutes all occurrences of identifiers according to the given map. Note that this substitution is
@@ -28,6 +47,13 @@ namespace storm {
             template<template<typename... Arguments> class MapType>
             Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const;
             
+            /*!
+             * Retrieves the return type of the expression.
+             *
+             * @return The return type of the expression.
+             */
+            ExpressionReturnType getReturnType() const;
+            
         private:
             /*!
              * Creates an expression with the given underlying base expression.
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index e145826b6..59bb99ac1 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -1,10 +1,16 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
 #define STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
 
+#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/BinaryRelationExpression.h"
+
 namespace storm {
     namespace expressions {
         class ExpressionVisitor {
-            
+            virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0;
+            virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0;
+            virtual void visit(BinaryRelationExpression const* expression) = 0;
         };
     }
 }
diff --git a/src/storage/expressions/IntegerConstantExpression.cpp b/src/storage/expressions/IntegerConstantExpression.cpp
new file mode 100644
index 000000000..0cbf541a7
--- /dev/null
+++ b/src/storage/expressions/IntegerConstantExpression.cpp
@@ -0,0 +1,9 @@
+#include "src/storage/expressions/IntegerConstantExpression.h"
+
+namespace storm {
+    namespace expressions {
+        IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::int_, constantName) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h
new file mode 100644
index 000000000..c39df1c77
--- /dev/null
+++ b/src/storage/expressions/IntegerConstantExpression.h
@@ -0,0 +1,15 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
+
+namespace storm {
+    namespace expressions {
+        class IntegerConstantExpression : public ConstantExpression {
+        public:
+            IntegerConstantExpression(std::string const& constantName);
+            virtual ~IntegerConstantExpression() = default;
+            
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
new file mode 100644
index 000000000..1d97ebf41
--- /dev/null
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
@@ -0,0 +1,9 @@
+#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
+
+namespace storm {
+    namespace expressions {
+        UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType) : UnaryExpression(returnType, std::move(argument)), functionType(functionType) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h
new file mode 100644
index 000000000..277ea6637
--- /dev/null
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h
@@ -0,0 +1,21 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
+
+namespace storm {
+    namespace expressions {
+        class UnaryBooleanFunctionExpression : public UnaryExpression {
+            /*!
+             * An enum type specifying the different functions applicable.
+             */
+            enum FunctionType {NOT};
+            
+            UnaryBooleanFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType);
+            virtual ~UnaryBooleanFunctionExpression() = default;
+            
+        private:
+            FunctionType FunctionType;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_ */
diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp
new file mode 100644
index 000000000..bf8ab5972
--- /dev/null
+++ b/src/storage/expressions/UnaryExpression.cpp
@@ -0,0 +1,9 @@
+#include "src/storage/expressions/UnaryExpression.h"
+
+namespace storm {
+    namespace expressions {
+        UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& argument) : BaseExpression(returnType), argument(std::move(argument)) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
new file mode 100644
index 000000000..1aee2b349
--- /dev/null
+++ b/src/storage/expressions/UnaryExpression.h
@@ -0,0 +1,18 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_
+
+namespace storm {
+    namespace expressions {
+        class UnaryExpression : public BaseExpression {
+        public:
+            UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& argument);
+            virtual ~UnaryExpression() = default;
+            
+            std::unique_ptr<BaseExpression> const& getArgument() const;
+        private:
+            std::unique_ptr<BaseExpression> argument;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
new file mode 100644
index 000000000..e3cc93fdb
--- /dev/null
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
@@ -0,0 +1,9 @@
+#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+
+namespace storm {
+    namespace expressions {
+        UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType) : UnaryExpression(returnType, std::move(argument)), functionType(functionType) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h
new file mode 100644
index 000000000..5dce0b84f
--- /dev/null
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h
@@ -0,0 +1,21 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_
+
+namespace storm {
+    namespace expressions {
+        class UnaryNumericalFunctionExpression : public UnaryExpression {
+            /*!
+             * An enum type specifying the different functions applicable.
+             */
+            enum FunctionType {MINUS, FLOOR, CEIL};
+            
+            UnaryNumericalFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType);
+            virtual ~UnaryNumericalFunctionExpression() = default;
+            
+        private:
+            FunctionType FunctionType;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_ */
diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
index c2d0b01cb..5a1a470ce 100644
--- a/src/storage/expressions/Valuation.h
+++ b/src/storage/expressions/Valuation.h
@@ -1,6 +1,8 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_VALUATION_H_
 #define STORM_STORAGE_EXPRESSIONS_VALUATION_H_
 
+#include <string>
+
 namespace storm {
     namespace expressions {
         class Valuation {
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
index bce5ec0dc..7b64707fd 100644
--- a/src/storage/expressions/VariableExpression.cpp
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -17,12 +17,12 @@ namespace storm {
         }
         
         bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not an integer.");
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not a boolean.");
             return evaluation.getBooleanValue(this->getVariableName());
         }
         
         double VariableExpression::evaluateAsDouble(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::double_), "Cannot evaluate expression as integer: return type is not an integer.");
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::double_), "Cannot evaluate expression as integer: return type is not a double.");
             return evaluation.getDoubleValue(this->getVariableName());
         }
         
@@ -52,5 +52,7 @@ namespace storm {
         std::unique_ptr<BaseExpression> ceil() const;
         
         void visit(ExpressionVisitor* visitor) const;
+        
+        virtual std::unique_ptr<BaseExpression> clonse() const;
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index 2a5381a53..d4d57907b 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -38,6 +38,8 @@ namespace storm {
             
             virtual void visit(ExpressionVisitor* visitor) const;
             
+            virtual std::unique_ptr<BaseExpression> clonse() const;
+            
         private:
             std::string variableName;
         };

From 232f72ffaa084c60312a5b0e3a10002fe140cd2e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 3 Apr 2014 22:02:58 +0200
Subject: [PATCH 055/147] Further work on new expression classes.

Former-commit-id: 4b0a6bca70981b34a2f15927445bdf8cf5588a57
---
 .../expressions/BooleanConstantExpression.cpp | 25 +++++++++++-
 .../expressions/BooleanConstantExpression.h   | 19 ++++++++++
 .../expressions/ConstantExpression.cpp        | 38 ++++++++++++++++++-
 src/storage/expressions/ConstantExpression.h  | 29 ++++++++++++++
 src/storage/expressions/ExpressionVisitor.h   |  2 +
 5 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp
index 8c40b02af..b9fa340b0 100644
--- a/src/storage/expressions/BooleanConstantExpression.cpp
+++ b/src/storage/expressions/BooleanConstantExpression.cpp
@@ -2,8 +2,31 @@
 
 namespace storm {
     namespace expressions {
-        BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::bool_, constantName) {
+        BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::bool_, constantName) {
             // Intentionally left empty.
         }
+        
+        BooleanConstantExpression::BooleanConstantExpression(BooleanConstantExpression const& other) : ConstantExpression(other) {
+            // Intentionally left empty.
+        }
+        
+        BooleanConstantExpression& BooleanConstantExpression::operator=(BooleanConstantExpression const& other) {
+            if (this != &other) {
+                ConstantExpression::operator=(other);
+            }
+            return *this;
+        }
+        
+        bool BooleanConstantExpression::evaluateAsBool(Valuation const& valuation) const {
+            return valuation.getBooleanValue(this->getConstantName());
+        }
+        
+        std::unique_ptr<BaseExpression> BooleanConstantExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new BooleanConstantExpression(*this));
+        }
+        
+        void BooleanConstantExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
index c337f01c0..1ff4a157a 100644
--- a/src/storage/expressions/BooleanConstantExpression.h
+++ b/src/storage/expressions/BooleanConstantExpression.h
@@ -7,8 +7,27 @@ namespace storm {
     namespace expressions {
         class BooleanConstantExpression : public ConstantExpression {
         public:
+            /*!
+             * Creates a boolean constant expression with the given return type and constant name.
+             *
+             * @param returnType The return type of the expression.
+             * @param constantName The name of the boolean constant associated with this expression.
+             */
             BooleanConstantExpression(std::string const& constantName);
+            
+            // Provide custom versions of copy construction and assignment.
+            BooleanConstantExpression(BooleanConstantExpression const& other);
+            BooleanConstantExpression& operator=(BooleanConstantExpression const& other);
+            
+            // Create default variants of move construction/assignment and virtual destructor.
+            BooleanConstantExpression(BooleanConstantExpression&&) = default;
+            BooleanConstantExpression& operator=(BooleanConstantExpression&&) = default;
             virtual ~BooleanConstantExpression() = default;
+            
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const;
+            virtual std::unique_ptr<BaseExpression> clone() const;
+            virtual void accept(ExpressionVisitor* visitor) const;
         };
     }
 }
diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp
index d6cbce747..9fcef7338 100644
--- a/src/storage/expressions/ConstantExpression.cpp
+++ b/src/storage/expressions/ConstantExpression.cpp
@@ -2,10 +2,46 @@
 
 namespace storm {
     namespace expressions {
-        ConstantExpression::ConstantExpression(ReturnType returnType, std::string const& constantName) : BaseExpression(returnType), constantName(constantName) {
+        ConstantExpression::ConstantExpression(ExpressionReturnType returnType, std::string const& constantName) : BaseExpression(returnType), constantName(constantName) {
             // Intentionally left empty.
         }
         
+        ConstantExpression::ConstantExpression(ConstantExpression const& other) : BaseExpression(other), constantName(other.getConstantName()) {
+            // Intentionally left empty.
+        }
+        
+        ConstantExpression& ConstantExpression::operator=(ConstantExpression const& other) {
+            if (this != &other) {
+                BaseExpression::operator=(other);
+                this->constantName = other.getConstantName();
+            }
+            return *this;
+        }
+        
+        bool ConstantExpression::isConstant() const {
+            return false;
+        }
+        
+        bool ConstantExpression::isTrue() const {
+            return false;
+        }
+        
+        bool ConstantExpression::isFalse() const {
+            return false;
+        }
+        
+        std::set<std::string> ConstantExpression::getVariables() const {
+            return std::set<std::string>();
+        }
+        
+        std::set<std::string> ConstantExpression::getConstants() const {
+            return {this->getConstantName()};
+        }
+        
+        std::unique_ptr<BaseExpression> ConstantExpression::simplify() const {
+            return this->clone();
+        }
+        
         std::string const& ConstantExpression::getConstantName() const {
             return this->constantName;
         }
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
index 08fb80321..8049c12cd 100644
--- a/src/storage/expressions/ConstantExpression.h
+++ b/src/storage/expressions/ConstantExpression.h
@@ -6,12 +6,41 @@
 namespace storm {
     namespace expressions {
         class ConstantExpression : public BaseExpression {
+        public:
+            /*!
+             * Creates a constant expression with the given return type and constant name.
+             *
+             * @param returnType The return type of the expression.
+             * @param constantName The name of the constant associated with this expression.
+             */
             ConstantExpression(ExpressionReturnType returnType, std::string const& constantName);
+            
+            // Provide custom versions of copy construction and assignment.
+            ConstantExpression(ConstantExpression const& other);
+            ConstantExpression& operator=(ConstantExpression const& other);
+            
+            // Create default variants of move construction/assignment and virtual destructor.
+            ConstantExpression(ConstantExpression&&) = default;
+            ConstantExpression& operator=(ConstantExpression&&) = default;
             virtual ~ConstantExpression() = default;
             
+            // Override base class methods.
+            virtual bool isConstant() const override;
+            virtual bool isTrue() const override;
+            virtual bool isFalse() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            
+            /*!
+             * Retrieves the name of the constant.
+             *
+             * @return The name of the constant.
+             */
             std::string const& getConstantName() const;
             
         private:
+            // The name of the constant.
             std::string constantName;
         };
     }
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index 59bb99ac1..94898e1a2 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -4,6 +4,7 @@
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BinaryRelationExpression.h"
+#include "src/storage/expressions/BooleanConstantExpression.h"
 
 namespace storm {
     namespace expressions {
@@ -11,6 +12,7 @@ namespace storm {
             virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0;
             virtual void visit(BinaryRelationExpression const* expression) = 0;
+            virtual void visit(BooleanConstantExpression const* expression) = 0;
         };
     }
 }

From ae06c7d677fe7903a415f9a33abfea6ead6d8f70 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 4 Apr 2014 15:11:25 +0200
Subject: [PATCH 056/147] Commit to switch workplace.

Former-commit-id: d828f3d2550a4acf933e3e066d10070b257c3ffc
---
 src/storage/expressions/BaseExpression.cpp    | 12 ++++
 src/storage/expressions/BaseExpression.h      | 19 ++++++-
 .../BinaryBooleanFunctionExpression.cpp       | 24 +++-----
 .../BinaryBooleanFunctionExpression.h         | 10 ++--
 .../BinaryNumericalFunctionExpression.cpp     | 44 ++++++---------
 .../BinaryNumericalFunctionExpression.h       | 10 ++--
 .../expressions/BinaryRelationExpression.cpp  | 26 +++------
 .../expressions/BinaryRelationExpression.h    | 10 ++--
 .../expressions/BooleanConstantExpression.cpp | 15 +----
 .../expressions/BooleanConstantExpression.h   | 11 ++--
 .../expressions/BooleanLiteralExpression.cpp  | 49 +++++++++++++++++
 .../expressions/BooleanLiteralExpression.h    | 49 +++++++++++++++++
 .../expressions/ConstantExpression.cpp        | 24 --------
 src/storage/expressions/ConstantExpression.h  | 11 +---
 .../expressions/DoubleConstantExpression.cpp  | 14 ++++-
 .../expressions/DoubleConstantExpression.h    | 16 ++++++
 .../expressions/DoubleLiteralExpression.cpp   | 41 ++++++++++++++
 .../expressions/DoubleLiteralExpression.h     | 47 ++++++++++++++++
 src/storage/expressions/ExpressionVisitor.h   | 28 ++++++++--
 .../expressions/IntegerConstantExpression.cpp | 18 +++++-
 .../expressions/IntegerConstantExpression.h   | 18 ++++++
 .../expressions/IntegerLiteralExpression.cpp  | 45 +++++++++++++++
 .../expressions/IntegerLiteralExpression.h    | 48 ++++++++++++++++
 src/storage/expressions/SimpleValuation.h     | 53 +++++++++++++++++-
 src/storage/expressions/SubstitutionVisitor.h |  2 -
 .../UnaryBooleanFunctionExpression.cpp        | 35 +++++++++++-
 .../UnaryBooleanFunctionExpression.h          | 35 +++++++++++-
 src/storage/expressions/UnaryExpression.cpp   | 26 ++++++++-
 src/storage/expressions/UnaryExpression.h     | 34 +++++++++++-
 .../UnaryNumericalFunctionExpression.cpp      | 34 +++++++++++-
 .../UnaryNumericalFunctionExpression.h        | 36 +++++++++++-
 src/storage/expressions/Valuation.h           | 24 ++++++++
 .../expressions/VariableExpression.cpp        | 43 ++++++---------
 src/storage/expressions/VariableExpression.h  | 55 ++++++++-----------
 34 files changed, 751 insertions(+), 215 deletions(-)
 create mode 100644 src/storage/expressions/BooleanLiteralExpression.cpp
 create mode 100644 src/storage/expressions/BooleanLiteralExpression.h
 create mode 100644 src/storage/expressions/DoubleLiteralExpression.cpp
 create mode 100644 src/storage/expressions/DoubleLiteralExpression.h
 create mode 100644 src/storage/expressions/IntegerLiteralExpression.cpp
 create mode 100644 src/storage/expressions/IntegerLiteralExpression.h

diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index 550e2209f..ca2db09f1 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -11,6 +11,14 @@ namespace storm {
             return this->returnType;
         }
         
+        bool BaseExpression::hasNumericalReturnType() const {
+            return this->getReturnType() == ExpressionReturnType::Double || this->getReturnType() == ExpressionReturnType::Int;
+        }
+        
+        bool BaseExpression::hasBooleanReturnType() const {
+            return this->getReturnType() == ExpressionReturnType::Bool;
+        }
+        
         int_fast64_t BaseExpression::evaluateAsInt(Valuation const& evaluation) const {
             LOG_ASSERT(false, "Unable to evaluate expression as integer.");
         }
@@ -23,6 +31,10 @@ namespace storm {
             LOG_ASSERT(false, "Unable to evaluate expression as double.");
         }
         
+        bool BaseExpression::isConstant() const {
+            return false;
+        }
+
         bool BaseExpression::isTrue() const {
             return false;
         }
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 545289b08..0698278da 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -1,6 +1,7 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
 
+#include <cstdint>
 #include <memory>
 #include <set>
 
@@ -13,7 +14,7 @@ namespace storm {
         /*!
          * Each node in an expression tree has a uniquely defined type from this enum.
          */
-        enum ExpressionReturnType {undefined, bool_, int_, double_};
+        enum class ExpressionReturnType {Undefined, Bool, Int, Double};
         
         /*!
          * The base class of all expression classes.
@@ -71,7 +72,7 @@ namespace storm {
              *
              * @return True iff the expression is constant.
              */
-            virtual bool isConstant() const = 0;
+            virtual bool isConstant() const;
             
             /*!
              * Checks if the expression is equal to the boolean literal true.
@@ -122,6 +123,20 @@ namespace storm {
              */
             virtual std::unique_ptr<BaseExpression> clone() const = 0;
             
+            /*!
+             * Retrieves whether the expression has a numerical return type, i.e., integer or double.
+             *
+             * @return True iff the expression has a numerical return type.
+             */
+            bool hasNumericalReturnType() const;
+            
+            /*!
+             * Retrieves whether the expression has a boolean return type.
+             *
+             * @return True iff the expression has a boolean return type.
+             */
+            bool hasBooleanReturnType() const;
+            
             /*!
              * Retrieves the return type of the expression.
              *
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index 749b1d1e1..e4034794e 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -10,26 +10,14 @@ namespace storm {
             return this->operatorType;
         }
         
-        BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other) : BinaryExpression(other), operatorType(other.getOperatorType()) {
-            // Intentionally left empty.
-        }
-        
-        BinaryBooleanFunctionExpression& BinaryBooleanFunctionExpression::operator=(BinaryBooleanFunctionExpression const& other) {
-            if (this != &other) {
-                BinaryExpression::operator=(other);
-                this->operatorType = other.getOperatorType();
-            }
-            return *this;
-        }
-        
         bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
             bool firstOperandEvaluation = this->getFirstOperand()->evaluateAsBool(valuation);
             bool secondOperandEvaluation = this->getSecondOperand()->evaluateAsBool(valuation);
             
             bool result;
             switch (this->getOperatorType()) {
-                case AND: result = firstOperandEvaluation && secondOperandEvaluation; break;
-                case OR: result = firstOperandEvaluation || secondOperandEvaluation; break;
+                case OperatorType::And: result = firstOperandEvaluation && secondOperandEvaluation; break;
+                case OperatorType::Or: result = firstOperandEvaluation || secondOperandEvaluation; break;
             }
             
             return result;
@@ -40,7 +28,7 @@ namespace storm {
             std::unique_ptr<BaseExpression> secondOperandSimplified = this->getSecondOperand()->simplify();
             
             switch (this->getOperatorType()) {
-                case AND: if (firstOperandSimplified->isTrue()) {
+                case OperatorType::And: if (firstOperandSimplified->isTrue()) {
                     return secondOperandSimplified;
                 } else if (firstOperandSimplified->isFalse()) {
                     return firstOperandSimplified;
@@ -50,7 +38,7 @@ namespace storm {
                     return secondOperandSimplified;
                 }
                 break;
-                case OR: if (firstOperandSimplified->isTrue()) {
+                case OperatorType::Or: if (firstOperandSimplified->isTrue()) {
                     return firstOperandSimplified;
                 } else if (firstOperandSimplified->isFalse()) {
                     return secondOperandSimplified;
@@ -68,6 +56,8 @@ namespace storm {
             visitor->visit(this);
         }
         
-        virtual std::unique_ptr<BaseExpression> clone() const override;
+        std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(*this));
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index f476550d0..eaabd1d56 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -10,7 +10,7 @@ namespace storm {
             /*!
              * An enum type specifying the different operators applicable.
              */
-            enum OperatorType {AND, OR};
+            enum class OperatorType {And, Or};
             
             /*!
              * Creates a binary boolean function expression with the given return type, operands and operator.
@@ -22,11 +22,9 @@ namespace storm {
              */
             BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& fistOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType);
             
-            // Provide custom versions of copy construction and assignment.
-            BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other);
-            BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression const& other);
-            
-            // Create default variants of move construction/assignment and virtual destructor.
+            // Instantiate constructors and assignments with their default implementations.
+            BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other) = default;
+            BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression const& other) = default;
             BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression&&) = default;
             BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression&&) = default;
             virtual ~BinaryBooleanFunctionExpression() = default;
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
index 61e491650..7139db695 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -9,43 +9,31 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other) : BinaryExpression(other), operatorType(this->getOperatorType()) {
-            // Intentionally left empty.
-        }
-        
-        BinaryNumericalFunctionExpression& BinaryNumericalFunctionExpression::operator=(BinaryNumericalFunctionExpression const& other) {
-            if (this != &other) {
-                BinaryExpression::operator=(other);
-                this->operatorType = other.getOperatorType();
-            }
-            return *this;
-        }
-        
         int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
-            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::int_, "Unable to evaluate expression as integer.");
+            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::Int, "Unable to evaluate expression as integer.");
             int_fast64_t firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation);
             int_fast64_t secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation);
             switch (this->getOperatorType()) {
-                case PLUS: return firstOperandEvaluation + secondOperandEvaluation; break;
-                case MINUS: return firstOperandEvaluation - secondOperandEvaluation; break;
-                case TIMES: return firstOperandEvaluation * secondOperandEvaluation; break;
-                case DIVIDE: return firstOperandEvaluation / secondOperandEvaluation; break;
-                case MIN: return std::min(firstOperandEvaluation, secondOperandEvaluation); break;
-                case MAX: return std::max(firstOperandEvaluation, secondOperandEvaluation); break;
+                case OperatorType::Plus: return firstOperandEvaluation + secondOperandEvaluation; break;
+                case OperatorType::Minus: return firstOperandEvaluation - secondOperandEvaluation; break;
+                case OperatorType::Times: return firstOperandEvaluation * secondOperandEvaluation; break;
+                case OperatorType::Divide: return firstOperandEvaluation / secondOperandEvaluation; break;
+                case OperatorType::Min: return std::min(firstOperandEvaluation, secondOperandEvaluation); break;
+                case OperatorType::Max: return std::max(firstOperandEvaluation, secondOperandEvaluation); break;
             }
         }
         
         double BinaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
-            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::int_, "Unable to evaluate expression as integer.");
-            double firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation);
-            double secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation);
+            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::Double, "Unable to evaluate expression as double.");
+            double firstOperandEvaluation = this->getFirstOperand()->evaluateAsDouble(valuation);
+            double secondOperandEvaluation = this->getSecondOperand()->evaluateAsDouble(valuation);
             switch (this->getOperatorType()) {
-                case PLUS: return firstOperandEvaluation + secondOperandEvaluation; break;
-                case MINUS: return firstOperandEvaluation - secondOperandEvaluation; break;
-                case TIMES: return firstOperandEvaluation * secondOperandEvaluation; break;
-                case DIVIDE: return firstOperandEvaluation / secondOperandEvaluation; break;
-                case MIN: return std::min(firstOperandEvaluation, secondOperandEvaluation); break;
-                case MAX: return std::max(firstOperandEvaluation, secondOperandEvaluation); break;
+                case OperatorType::Plus: return static_cast<double>(firstOperandEvaluation + secondOperandEvaluation); break;
+                case OperatorType::Minus: return static_cast<double>(firstOperandEvaluation - secondOperandEvaluation); break;
+                case OperatorType::Times: return static_cast<double>(firstOperandEvaluation * secondOperandEvaluation); break;
+                case OperatorType::Divide: return static_cast<double>(firstOperandEvaluation / secondOperandEvaluation); break;
+                case OperatorType::Min: return static_cast<double>(std::min(firstOperandEvaluation, secondOperandEvaluation)); break;
+                case OperatorType::Max: return static_cast<double>(std::max(firstOperandEvaluation, secondOperandEvaluation)); break;
             }
         }
         
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
index 56ae3b55d..92d4bc0d2 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -10,7 +10,7 @@ namespace storm {
             /*!
              * An enum type specifying the different operators applicable.
              */
-            enum OperatorType {PLUS, MINUS, TIMES, DIVIDE, MIN, MAX};
+            enum class OperatorType {Plus, Minus, Times, Divide, Min, Max};
             
             /*!
              * Constructs a binary numerical function expression with the given return type, operands and operator.
@@ -22,11 +22,9 @@ namespace storm {
              */
             BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType);
             
-            // Provide custom versions of copy construction and assignment.
-            BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other);
-            BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression const& other);
-            
-            // Create default variants of move construction/assignment and virtual destructor.
+            // Instantiate constructors and assignments with their default implementations.
+            BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other) = default;
+            BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression const& other) = default;
             BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression&&) = default;
             BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression&&) = default;
             virtual ~BinaryNumericalFunctionExpression() = default;
diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp
index a203ec2fb..fb4123fca 100644
--- a/src/storage/expressions/BinaryRelationExpression.cpp
+++ b/src/storage/expressions/BinaryRelationExpression.cpp
@@ -5,29 +5,17 @@ namespace storm {
         BinaryRelationExpression::BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, RelationType relationType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), relationType(relationType) {
             // Intentionally left empty.
         }
-        
-        BinaryRelationExpression::BinaryRelationExpression(BinaryRelationExpression const& other) : BinaryExpression(other), relationType(other.getRelationType()) {
-            // Intentionally left empty.
-        }
-        
-        BinaryRelationExpression& BinaryRelationExpression::operator=(BinaryRelationExpression const& other) {
-            if (this != &other) {
-                BinaryExpression::operator=(other);
-                this->relationType = other.getRelationType();
-            }
-            return *this;
-        }
-        
+                
         bool BinaryRelationExpression::evaluateAsBool(Valuation const& valuation) const {
             double firstOperandEvaluated = this->getFirstOperand()->evaluateAsDouble(valuation);
             double secondOperandEvaluated = this->getSecondOperand()->evaluateAsDouble(valuation);
             switch (this->getRelationType()) {
-                case EQUAL: return firstOperandEvaluated == secondOperandEvaluated; break;
-                case NOT_EQUAL: return firstOperandEvaluated != secondOperandEvaluated; break;
-                case GREATER: return firstOperandEvaluated > secondOperandEvaluated; break;
-                case GREATER_OR_EQUAL: return firstOperandEvaluated >= secondOperandEvaluated; break;
-                case LESS: return firstOperandEvaluated < secondOperandEvaluated; break;
-                case LESS_OR_EQUAL: return firstOperandEvaluated <= secondOperandEvaluated; break;
+                case RelationType::Equal: return firstOperandEvaluated == secondOperandEvaluated; break;
+                case RelationType::NotEqual: return firstOperandEvaluated != secondOperandEvaluated; break;
+                case RelationType::Greater: return firstOperandEvaluated > secondOperandEvaluated; break;
+                case RelationType::GreaterOrEqual: return firstOperandEvaluated >= secondOperandEvaluated; break;
+                case RelationType::Less: return firstOperandEvaluated < secondOperandEvaluated; break;
+                case RelationType::LessOrEqual: return firstOperandEvaluated <= secondOperandEvaluated; break;
             }
         }
         
diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h
index 7b45cc1c1..31145ec30 100644
--- a/src/storage/expressions/BinaryRelationExpression.h
+++ b/src/storage/expressions/BinaryRelationExpression.h
@@ -10,7 +10,7 @@ namespace storm {
             /*!
              * An enum type specifying the different relations applicable.
              */
-            enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL};
+            enum class RelationType {Equal, NotEqual, Less, LessOrEqual, Greater, GreaterOrEqual};
             
             /*!
              * Creates a binary relation expression with the given return type, operands and relation type.
@@ -22,11 +22,9 @@ namespace storm {
              */
             BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, RelationType relationType);
             
-            // Provide custom versions of copy construction and assignment.
-            BinaryRelationExpression(BinaryRelationExpression const& other);
-            BinaryRelationExpression& operator=(BinaryRelationExpression const& other);
-            
-            // Create default variants of move construction/assignment and virtual destructor.
+            // Instantiate constructors and assignments with their default implementations.
+            BinaryRelationExpression(BinaryRelationExpression const& other) = default;
+            BinaryRelationExpression& operator=(BinaryRelationExpression const& other) = default;
             BinaryRelationExpression(BinaryRelationExpression&&) = default;
             BinaryRelationExpression& operator=(BinaryRelationExpression&&) = default;
             virtual ~BinaryRelationExpression() = default;
diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp
index b9fa340b0..c20d8a8b7 100644
--- a/src/storage/expressions/BooleanConstantExpression.cpp
+++ b/src/storage/expressions/BooleanConstantExpression.cpp
@@ -2,21 +2,10 @@
 
 namespace storm {
     namespace expressions {
-        BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::bool_, constantName) {
+        BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::Bool, constantName) {
             // Intentionally left empty.
         }
-        
-        BooleanConstantExpression::BooleanConstantExpression(BooleanConstantExpression const& other) : ConstantExpression(other) {
-            // Intentionally left empty.
-        }
-        
-        BooleanConstantExpression& BooleanConstantExpression::operator=(BooleanConstantExpression const& other) {
-            if (this != &other) {
-                ConstantExpression::operator=(other);
-            }
-            return *this;
-        }
-        
+                
         bool BooleanConstantExpression::evaluateAsBool(Valuation const& valuation) const {
             return valuation.getBooleanValue(this->getConstantName());
         }
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
index 1ff4a157a..7b72fdc4e 100644
--- a/src/storage/expressions/BooleanConstantExpression.h
+++ b/src/storage/expressions/BooleanConstantExpression.h
@@ -8,18 +8,15 @@ namespace storm {
         class BooleanConstantExpression : public ConstantExpression {
         public:
             /*!
-             * Creates a boolean constant expression with the given return type and constant name.
+             * Creates a boolean constant expression with the given constant name.
              *
-             * @param returnType The return type of the expression.
              * @param constantName The name of the boolean constant associated with this expression.
              */
             BooleanConstantExpression(std::string const& constantName);
             
-            // Provide custom versions of copy construction and assignment.
-            BooleanConstantExpression(BooleanConstantExpression const& other);
-            BooleanConstantExpression& operator=(BooleanConstantExpression const& other);
-            
-            // Create default variants of move construction/assignment and virtual destructor.
+            // Instantiate constructors and assignments with their default implementations.
+            BooleanConstantExpression(BooleanConstantExpression const& other) = default;
+            BooleanConstantExpression& operator=(BooleanConstantExpression const& other) = default;
             BooleanConstantExpression(BooleanConstantExpression&&) = default;
             BooleanConstantExpression& operator=(BooleanConstantExpression&&) = default;
             virtual ~BooleanConstantExpression() = default;
diff --git a/src/storage/expressions/BooleanLiteralExpression.cpp b/src/storage/expressions/BooleanLiteralExpression.cpp
new file mode 100644
index 000000000..371e9f7e9
--- /dev/null
+++ b/src/storage/expressions/BooleanLiteralExpression.cpp
@@ -0,0 +1,49 @@
+#include "src/storage/expressions/BooleanLiteralExpression.h"
+
+namespace storm {
+    namespace expressions {
+        BooleanLiteralExpression::BooleanLiteralExpression(bool value) : value(value) {
+            // Intentionally left empty.
+        }
+        
+        bool BooleanLiteralExpression::evaluateAsBool(Valuation const& valuation) const {
+            return this->getValue();
+        }
+        
+        bool BooleanLiteralExpression::isConstant() const {
+            return true;
+        }
+        
+        bool BooleanLiteralExpression::isTrue() const {
+            return this->getValue() == true;
+        }
+        
+        bool BooleanLiteralExpression::isFalse() const {
+            return this->getValue() == false;
+        }
+        
+        std::set<std::string> BooleanLiteralExpression::getVariables() const {
+            return {};
+        }
+        
+        std::set<std::string> BooleanLiteralExpression::getConstants() const {
+            return {};
+        }
+        
+        std::unique_ptr<BaseExpression> BooleanLiteralExpression::simplify() const {
+            return this->clone();
+        }
+        
+        void BooleanLiteralExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> BooleanLiteralExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(*this));
+        }
+        
+        bool BooleanLiteralExpression::getValue() const {
+            return this->value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanLiteralExpression.h b/src/storage/expressions/BooleanLiteralExpression.h
new file mode 100644
index 000000000..837190c95
--- /dev/null
+++ b/src/storage/expressions/BooleanLiteralExpression.h
@@ -0,0 +1,49 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class BooleanLiteralExpression : BaseExpression {
+        public:
+            /*!
+             * Creates a boolean literal expression with the given value.
+             *
+             * @param value The value of the boolean literal.
+             */
+            BooleanLiteralExpression(bool value);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            BooleanLiteralExpression(BooleanLiteralExpression const& other) = default;
+            BooleanLiteralExpression& operator=(BooleanLiteralExpression const& other) = default;
+            BooleanLiteralExpression(BooleanLiteralExpression&&) = default;
+            BooleanLiteralExpression& operator=(BooleanLiteralExpression&&) = default;
+            virtual ~BooleanLiteralExpression() = default;
+
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual bool isConstant() const override;
+            virtual bool isTrue() const override;
+            virtual bool isFalse() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the value of the boolean literal.
+             *
+             * @return The value of the boolean literal.
+             */
+            bool getValue() const;
+            
+        private:
+            // The value of the boolean literal.
+            bool value;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp
index 9fcef7338..08bd26a95 100644
--- a/src/storage/expressions/ConstantExpression.cpp
+++ b/src/storage/expressions/ConstantExpression.cpp
@@ -6,30 +6,6 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        ConstantExpression::ConstantExpression(ConstantExpression const& other) : BaseExpression(other), constantName(other.getConstantName()) {
-            // Intentionally left empty.
-        }
-        
-        ConstantExpression& ConstantExpression::operator=(ConstantExpression const& other) {
-            if (this != &other) {
-                BaseExpression::operator=(other);
-                this->constantName = other.getConstantName();
-            }
-            return *this;
-        }
-        
-        bool ConstantExpression::isConstant() const {
-            return false;
-        }
-        
-        bool ConstantExpression::isTrue() const {
-            return false;
-        }
-        
-        bool ConstantExpression::isFalse() const {
-            return false;
-        }
-        
         std::set<std::string> ConstantExpression::getVariables() const {
             return std::set<std::string>();
         }
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
index 8049c12cd..b8b985ac2 100644
--- a/src/storage/expressions/ConstantExpression.h
+++ b/src/storage/expressions/ConstantExpression.h
@@ -15,19 +15,14 @@ namespace storm {
              */
             ConstantExpression(ExpressionReturnType returnType, std::string const& constantName);
             
-            // Provide custom versions of copy construction and assignment.
-            ConstantExpression(ConstantExpression const& other);
-            ConstantExpression& operator=(ConstantExpression const& other);
-            
-            // Create default variants of move construction/assignment and virtual destructor.
+            // Instantiate constructors and assignments with their default implementations.
+            ConstantExpression(ConstantExpression const& other) = default;
+            ConstantExpression& operator=(ConstantExpression const& other) = default;
             ConstantExpression(ConstantExpression&&) = default;
             ConstantExpression& operator=(ConstantExpression&&) = default;
             virtual ~ConstantExpression() = default;
             
             // Override base class methods.
-            virtual bool isConstant() const override;
-            virtual bool isTrue() const override;
-            virtual bool isFalse() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             virtual std::unique_ptr<BaseExpression> simplify() const override;
diff --git a/src/storage/expressions/DoubleConstantExpression.cpp b/src/storage/expressions/DoubleConstantExpression.cpp
index 25fa035d4..c0c7925dc 100644
--- a/src/storage/expressions/DoubleConstantExpression.cpp
+++ b/src/storage/expressions/DoubleConstantExpression.cpp
@@ -2,8 +2,20 @@
 
 namespace storm {
     namespace expressions {
-        DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::double_, constantName) {
+        DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::Double, constantName) {
             // Intentionally left empty.
         }
+        
+        double DoubleConstantExpression::evaluateAsDouble(Valuation const& valuation) const {
+            return valuation.getDoubleValue(this->getConstantName());
+        }
+        
+        std::unique_ptr<BaseExpression> DoubleConstantExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new DoubleConstantExpression(*this));
+        }
+        
+        void DoubleConstantExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h
index fc5725642..28455190f 100644
--- a/src/storage/expressions/DoubleConstantExpression.h
+++ b/src/storage/expressions/DoubleConstantExpression.h
@@ -7,8 +7,24 @@ namespace storm {
     namespace expressions {
         class DoubleConstantExpression : public ConstantExpression {
         public:
+            /*!
+             * Creates a double constant expression with the given constant name.
+             *
+             * @param constantName The name of the double constant associated with this expression.
+             */
             DoubleConstantExpression(std::string const& constantName);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            DoubleConstantExpression(DoubleConstantExpression const& other) = default;
+            DoubleConstantExpression& operator=(DoubleConstantExpression const& other) = default;
+            DoubleConstantExpression(DoubleConstantExpression&&) = default;
+            DoubleConstantExpression& operator=(DoubleConstantExpression&&) = default;
             virtual ~DoubleConstantExpression() = default;
+            
+            // Override base class methods.
+            virtual double evaluateAsDouble(Valuation const& valuation) const;
+            virtual std::unique_ptr<BaseExpression> clone() const;
+            virtual void accept(ExpressionVisitor* visitor) const;
         };
     }
 }
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
new file mode 100644
index 000000000..a96bdcdd9
--- /dev/null
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -0,0 +1,41 @@
+#include "src/storage/expressions/DoubleLiteralExpression.h"
+
+namespace storm {
+    namespace expressions {
+        DoubleLiteralExpression::DoubleLiteralExpression(double value) : value(value) {
+            // Intentionally left empty.
+        }
+        
+        double DoubleLiteralExpression::evaluateAsDouble(Valuation const& valuation) const {
+            return this->getValue();
+        }
+        
+        bool DoubleLiteralExpression::isConstant() const {
+            return true;
+        }
+        
+        std::set<std::string> DoubleLiteralExpression::getVariables() const {
+            return {};
+        }
+        
+        std::set<std::string> DoubleLiteralExpression::getConstants() const {
+            return {};
+        }
+        
+        std::unique_ptr<BaseExpression> DoubleLiteralExpression::simplify() const {
+            return this->clone();
+        }
+        
+        void DoubleLiteralExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> DoubleLiteralExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new DoubleLiteralExpression(*this));
+        }
+        
+        double DoubleLiteralExpression::getValue() const {
+            return this->value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
new file mode 100644
index 000000000..b15e5e013
--- /dev/null
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -0,0 +1,47 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class DoubleLiteralExpression : BaseExpression {
+        public:
+            /*!
+             * Creates an double literal expression with the given value.
+             *
+             * @param value The value of the double literal.
+             */
+            DoubleLiteralExpression(double value);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            DoubleLiteralExpression(DoubleLiteralExpression const& other) = default;
+            DoubleLiteralExpression& operator=(DoubleLiteralExpression const& other) = default;
+            DoubleLiteralExpression(DoubleLiteralExpression&&) = default;
+            DoubleLiteralExpression& operator=(DoubleLiteralExpression&&) = default;
+            virtual ~DoubleLiteralExpression() = default;
+            
+            // Override base class methods.
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual bool isConstant() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the value of the double literal.
+             *
+             * @return The value of the double literal.
+             */
+            double getValue() const;
+            
+        private:
+            // The value of the double literal.
+            double value;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index 94898e1a2..4bd2e8d29 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -1,18 +1,36 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
 #define STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
 
-#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
-#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/BinaryRelationExpression.h"
-#include "src/storage/expressions/BooleanConstantExpression.h"
-
 namespace storm {
     namespace expressions {
+        // Forward-declare all expression classes.
+        class BinaryBooleanFunctionExpression;
+        class BinaryNumericalFunctionExpression;
+        class BinaryRelationExpression;
+        class BooleanConstantExpression;
+        class DoubleConstantExpression;
+        class IntegerConstantExpression;
+        class IntegerConstantExpression;
+        class VariableExpression;
+        class UnaryBooleanFunctionExpression;
+        class UnaryNumericalFunctionExpression;
+        class BooleanLiteralExpression;
+        class IntegerLiteralExpression;
+        class DoubleLiteralExpression;
+        
         class ExpressionVisitor {
             virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0;
             virtual void visit(BinaryRelationExpression const* expression) = 0;
             virtual void visit(BooleanConstantExpression const* expression) = 0;
+            virtual void visit(DoubleConstantExpression const* expression) = 0;
+            virtual void visit(IntegerConstantExpression const* expression) = 0;
+            virtual void visit(VariableExpression const* expression) = 0;
+            virtual void visit(UnaryBooleanFunctionExpression const* expression) = 0;
+            virtual void visit(UnaryNumericalFunctionExpression const* expression) = 0;
+            virtual void visit(BooleanLiteralExpression const* expression) = 0;
+            virtual void visit(IntegerLiteralExpression const* expression) = 0;
+            virtual void visit(DoubleLiteralExpression const* expression) = 0;
         };
     }
 }
diff --git a/src/storage/expressions/IntegerConstantExpression.cpp b/src/storage/expressions/IntegerConstantExpression.cpp
index 0cbf541a7..87e109423 100644
--- a/src/storage/expressions/IntegerConstantExpression.cpp
+++ b/src/storage/expressions/IntegerConstantExpression.cpp
@@ -2,8 +2,24 @@
 
 namespace storm {
     namespace expressions {
-        IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(ReturnType::int_, constantName) {
+        IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::Int, constantName) {
             // Intentionally left empty.
         }
+        
+        int_fast64_t IntegerConstantExpression::evaluateAsInteger(Valuation const& valuation) const {
+            return valuation.getIntegerValue(this->getConstantName());
+        }
+        
+        double IntegerConstantExpression::evaluateAsDouble(Valuation const& valuation) const {
+            return static_cast<double>(valuation.getIntegerValue(this->getConstantName()));
+        }
+        
+        std::unique_ptr<BaseExpression> IntegerConstantExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new IntegerConstantExpression(*this));
+        }
+        
+        void IntegerConstantExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h
index c39df1c77..402679163 100644
--- a/src/storage/expressions/IntegerConstantExpression.h
+++ b/src/storage/expressions/IntegerConstantExpression.h
@@ -1,13 +1,31 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
 
+#include "src/storage/expressions/ConstantExpression.h"
+
 namespace storm {
     namespace expressions {
         class IntegerConstantExpression : public ConstantExpression {
         public:
+            /*!
+             * Creates an integer constant expression with the given constant name.
+             *
+             * @param constantName The name of the integer constant associated with this expression.
+             */
             IntegerConstantExpression(std::string const& constantName);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            IntegerConstantExpression(IntegerConstantExpression const& other) = default;
+            IntegerConstantExpression& operator=(IntegerConstantExpression const& other) = default;
+            IntegerConstantExpression(IntegerConstantExpression&&) = default;
+            IntegerConstantExpression& operator=(IntegerConstantExpression&&) = default;
             virtual ~IntegerConstantExpression() = default;
             
+            // Override base class methods.
+            virtual int_fast64_t evaluateAsInteger(Valuation const& valuation) const;
+            virtual double evaluateAsDouble(Valuation const& valuation) const;
+            virtual std::unique_ptr<BaseExpression> clone() const;
+            virtual void accept(ExpressionVisitor* visitor) const;
         };
     }
 }
diff --git a/src/storage/expressions/IntegerLiteralExpression.cpp b/src/storage/expressions/IntegerLiteralExpression.cpp
new file mode 100644
index 000000000..ad74e58bd
--- /dev/null
+++ b/src/storage/expressions/IntegerLiteralExpression.cpp
@@ -0,0 +1,45 @@
+#include "src/storage/expressions/IntegerLiteralExpression.h"
+
+namespace storm {
+    namespace expressions {
+        IntegerLiteralExpression::IntegerLiteralExpression(int_fast64_t value) : value(value) {
+            // Intentionally left empty.
+        }
+        
+        int_fast64_t IntegerLiteralExpression::evaluateAsInt(Valuation const& valuation) const {
+            return this->getValue();
+        }
+        
+        double IntegerLiteralExpression::evaluateAsDouble(Valuation const& valuation) const {
+            return static_cast<double>(this->getValue());
+        }
+        
+        bool IntegerLiteralExpression::isConstant() const {
+            return true;
+        }
+        
+        std::set<std::string> IntegerLiteralExpression::getVariables() const {
+            return {};
+        }
+        
+        std::set<std::string> IntegerLiteralExpression::getConstants() const {
+            return {};
+        }
+        
+        std::unique_ptr<BaseExpression> IntegerLiteralExpression::simplify() const {
+            return this->clone();
+        }
+        
+        void IntegerLiteralExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> IntegerLiteralExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new IntegerLiteralExpression(*this));
+        }
+        
+        int_fast64_t IntegerLiteralExpression::getValue() const {
+            return this->value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
new file mode 100644
index 000000000..1fc1b03f7
--- /dev/null
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -0,0 +1,48 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class IntegerLiteralExpression : BaseExpression {
+        public:
+            /*!
+             * Creates an integer literal expression with the given value.
+             *
+             * @param value The value of the integer literal.
+             */
+            IntegerLiteralExpression(int_fast64_t value);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            IntegerLiteralExpression(IntegerLiteralExpression const& other) = default;
+            IntegerLiteralExpression& operator=(IntegerLiteralExpression const& other) = default;
+            IntegerLiteralExpression(IntegerLiteralExpression&&) = default;
+            IntegerLiteralExpression& operator=(IntegerLiteralExpression&&) = default;
+            virtual ~IntegerLiteralExpression() = default;
+            
+            // Override base class methods.
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual bool isConstant() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the value of the integer literal.
+             *
+             * @return The value of the integer literal.
+             */
+            int_fast64_t getValue() const;
+            
+        private:
+            // The value of the integer literal.
+            int_fast64_t value;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 399a6d7f4..f4808face 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -3,7 +3,6 @@
 
 #include <memory>
 #include <vector>
-#include <string>
 #include <unordered_map>
 
 #include "src/storage/expressions/Valuation.h"
@@ -12,30 +11,82 @@ namespace storm {
     namespace expressions {
         class SimpleValuation : public Valuation {
         public:
+            /*!
+             * Creates a simple valuation that can hold the given number of boolean, integer and double variables.
+             *
+             * @param booleanVariableCount The number of boolean variables in the valuation.
+             * @param integerVariableCount The number of integer variables in the valuation.
+             * @param doubleVariableCount The number of double variables in the valuation.
+             */
             SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount);
             
+            /*!
+             * Creates a simple evaluation based on the given identifier to index map and value containers for the
+             * different types of variables.
+             *
+             * @param identifierToIndexMap A shared pointer to a mapping from identifier to their local indices in the
+             * value containers.
+             * @param booleanValues The value container for all boolean identifiers.
+             * @param integerValues The value container for all integer identifiers.
+             * @param doubleValues The value container for all double identifiers.
+             */
             SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues);
 
+            // Instantiate some constructors and assignments with their default implementations.
             SimpleValuation() = default;
             SimpleValuation(SimpleValuation const&) = default;
             SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
             SimpleValuation& operator=(SimpleValuation&&) = default;
             
+            /*!
+             * Sets the index of the identifier with the given name to the given value.
+             *
+             * @param name The name of the identifier for which to set the index.
+             * @param index The new index of the identifier.
+             */
             void setIdentifierIndex(std::string const& name, uint_fast64_t index);
             
+            /*!
+             * Sets the value of the boolean identifier with the given name to the given value.
+             *
+             * @param name The name of the boolean identifier whose value to set.
+             * @param value The new value of the boolean identifier.
+             */
             void setBooleanValue(std::string const& name, bool value);
+
+            /*!
+             * Sets the value of the integer identifier with the given name to the given value.
+             *
+             * @param name The name of the integer identifier whose value to set.
+             * @param value The new value of the integer identifier.
+             */
             void setIntegerValue(std::string const& name, int_fast64_t value);
+
+            /*!
+             * Sets the value of the double identifier with the given name to the given value.
+             *
+             * @param name The name of the double identifier whose value to set.
+             * @param value The new value of the double identifier.
+             */
             void setDoubleValue(std::string const& name, double value);
             
+            // Override base class methods.
             virtual bool getBooleanValue(std::string const& name) const override;
             virtual int_fast64_t getIntegerValue(std::string const& name) const override;
             virtual double getDoubleValue(std::string const& name) const override;
             
         private:
+            // A mapping of identifiers to their local indices in the value containers.
             std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap;
+            
+            // The value container for all boolean identifiers.
             std::vector<bool> booleanValues;
+            
+            // The value container for all integer identifiers.
             std::vector<int_fast64_t> integerValues;
+            
+            // The value container for all double identifiers.
             std::vector<double> doubleValues;
         };
     }
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index f65482e3c..db2947e2e 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -10,8 +10,6 @@ namespace storm {
         public:
             template<template<typename... Arguments> class MapType>
             Expression substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap);
-            
-            
         };
     }
 }
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
index 1d97ebf41..d25460c3c 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
@@ -1,9 +1,42 @@
 #include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/BooleanLiteralExpression.h"
 
 namespace storm {
     namespace expressions {
-        UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType) : UnaryExpression(returnType, std::move(argument)), functionType(functionType) {
+        UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType) : UnaryExpression(returnType, std::move(operand)), operatorType(operatorType) {
             // Intentionally left empty.
         }
+        
+        OperatorType UnaryBooleanFunctionExpression::getOperatorType() const {
+            return this->operatorType;
+        }
+        
+        bool UnaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
+            bool operandEvaluated = this->getOperand()->evaluateAsBool(valuation);
+            switch (this->getOperatorType()) {
+                case OperatorType::Not: return !operandEvaluated; break;
+            }
+        }
+        
+        std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::simplify() const {
+            std::unique_ptr<BaseExpression> operandSimplified = this->getOperand()->simplify();
+            switch (this->getOperatorType()) {
+                case OperatorType::Not: if (operandSimplified->isTrue()) {
+                    return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(false));
+                } else {
+                    return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(true));
+                }
+            }
+            
+            return UnaryBooleanFunctionExpression(this->getReturnType(), std::move(operandSimplified), this->getOperatorType());
+        }
+        
+        void UnaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(*this));
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h
index 277ea6637..8453f99e0 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h
@@ -1,19 +1,48 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
 
+#include "src/storage/expressions/UnaryExpression.h"
+
 namespace storm {
     namespace expressions {
         class UnaryBooleanFunctionExpression : public UnaryExpression {
             /*!
              * An enum type specifying the different functions applicable.
              */
-            enum FunctionType {NOT};
+            enum class OperatorType {Not};
             
-            UnaryBooleanFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType);
+            /*!
+             * Creates a unary boolean function expression with the given return type, operand and operator.
+             *
+             * @param returnType The return type of the expression.
+             * @param operand The operand of the expression.
+             * @param operatorType The operator of the expression.
+             */
+            UnaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType);
+
+            // Instantiate constructors and assignments with their default implementations.
+            UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& other) = default;
+            UnaryBooleanFunctionExpression& operator=(UnaryBooleanFunctionExpression const& other) = default;
+            UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression&&) = default;
+            UnaryBooleanFunctionExpression& operator=(UnaryBooleanFunctionExpression&&) = default;
             virtual ~UnaryBooleanFunctionExpression() = default;
             
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+
+            /*!
+             * Retrieves the operator associated with this expression.
+             *
+             * @return The operator associated with this expression.
+             */
+            OperatorType getOperatorType() const;
+            
         private:
-            FunctionType FunctionType;
+            // The operator of this expression.
+            OperatorType operatorType;
         };
     }
 }
diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp
index bf8ab5972..e0573d813 100644
--- a/src/storage/expressions/UnaryExpression.cpp
+++ b/src/storage/expressions/UnaryExpression.cpp
@@ -2,8 +2,32 @@
 
 namespace storm {
     namespace expressions {
-        UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& argument) : BaseExpression(returnType), argument(std::move(argument)) {
+        UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand) : BaseExpression(returnType), operand(std::move(operand)) {
             // Intentionally left empty.
         }
+        
+        UnaryExpression::UnaryExpression(UnaryExpression const& other) : BaseExpression(other), operand(other.getOperand()->clone()) {
+            // Intentionally left empty.
+        }
+        
+        UnaryExpression& UnaryExpression::operator=(UnaryExpression const& other) {
+            if (this != &other) {
+                BaseExpression::operator=(other);
+                this->operand = other.getOperand()->clone();
+            }
+            return *this;
+        }
+
+        bool UnaryExpression::isConstant() const {
+            return this->getOperand()->isConstant();
+        }
+        
+        std::set<std::string> UnaryExpression::getVariables() const {
+            return this->getOperand()->getVariables();
+        }
+        
+        std::set<std::string> UnaryExpression::getConstants() const {
+            return this->getOperand()->getVariables();
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
index 1aee2b349..c0d4acf33 100644
--- a/src/storage/expressions/UnaryExpression.h
+++ b/src/storage/expressions/UnaryExpression.h
@@ -1,16 +1,44 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_
 
+#include "src/storage/expressions/BaseExpression.h"
+
 namespace storm {
     namespace expressions {
         class UnaryExpression : public BaseExpression {
         public:
-            UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& argument);
+            /*!
+             * Creates a unary expression with the given return type and operand.
+             *
+             * @param returnType The return type of the expression.
+             * @param operand The operand of the unary expression.
+             */
+            UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand);
+
+            // Provide custom versions of copy construction and assignment.
+            UnaryExpression(UnaryExpression const& other);
+            UnaryExpression& operator=(UnaryExpression const& other);
+            
+            // Create default variants of move construction/assignment and virtual destructor.
+            UnaryExpression(UnaryExpression&&) = default;
+            UnaryExpression& operator=(UnaryExpression&&) = default;
             virtual ~UnaryExpression() = default;
             
-            std::unique_ptr<BaseExpression> const& getArgument() const;
+            // Override base class methods.
+            virtual bool isConstant() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            
+            /*!
+             * Retrieves the operand of the unary expression.
+             *
+             * @return The operand of the unary expression.
+             */
+            std::unique_ptr<BaseExpression> const& getOperand() const;
+            
         private:
-            std::unique_ptr<BaseExpression> argument;
+            // The operand of the unary expression.
+            std::unique_ptr<BaseExpression> operand;
         };
     }
 }
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
index e3cc93fdb..fc8ef625b 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
@@ -1,9 +1,41 @@
+#include <cmath>
+
 #include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
 
 namespace storm {
     namespace expressions {
-        UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType) : UnaryExpression(returnType, std::move(argument)), functionType(functionType) {
+        UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType) : UnaryExpression(returnType, std::move(operand)), operatorType(operatorType) {
             // Intentionally left empty.
         }
+        
+        int_fast64_t UnaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
+            int_fast64_t operandEvaluated = this->getOperand()->evaluateAsInt(valuation);
+            switch (this->getOperatorType()) {
+                case OperatorType::Minus: return -operandEvaluated; break;
+                case OperatorType::Floor: return std::floor(operandEvaluated); break;
+                case OperatorType::Ceil: return std::ceil(operandEvaluated); break;
+            }
+        }
+        
+        double UnaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
+            double operandEvaluated = this->getOperand()->evaluateAsDouble(valuation);
+            switch (this->getOperatorType()) {
+                case OperatorType::Minus: return -operandEvaluated; break;
+                case OperatorType::Floor: return std::floor(operandEvaluated); break;
+                case OperatorType::Ceil: return std::ceil(operandEvaluated); break;
+            }
+        }
+        
+        std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::simplify() const {
+            return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getReturnType(), this->getOperand()->simplify(), this->getOperatorType()));
+        }
+        
+        void UnaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(*this));
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h
index 5dce0b84f..7bbba69ca 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h
@@ -1,19 +1,49 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_
 
+#include "src/storage/expressions/UnaryExpression.h"
+
 namespace storm {
     namespace expressions {
         class UnaryNumericalFunctionExpression : public UnaryExpression {
             /*!
              * An enum type specifying the different functions applicable.
              */
-            enum FunctionType {MINUS, FLOOR, CEIL};
+            enum class OperatorType {Minus, Floor, Ceil};
+            
+            /*!
+             * Creates a unary numerical function expression with the given return type, operand and operator.
+             *
+             * @param returnType The return type of the expression.
+             * @param operand The operand of the expression.
+             * @param operatorType The operator of the expression.
+             */
+            UnaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType);
             
-            UnaryNumericalFunctionExpression(ReturnType returnType, std::unique_ptr<BaseExpression>&& argument, FunctionType functionType);
+            // Instantiate constructors and assignments with their default implementations.
+            UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& other) = default;
+            UnaryNumericalFunctionExpression& operator=(UnaryNumericalFunctionExpression const& other) = default;
+            UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression&&) = default;
+            UnaryNumericalFunctionExpression& operator=(UnaryNumericalFunctionExpression&&) = default;
             virtual ~UnaryNumericalFunctionExpression() = default;
             
+            // Override base class methods.
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+            
+            /*!
+             * Retrieves the operator associated with this expression.
+             *
+             * @return The operator associated with this expression.
+             */
+            OperatorType getOperatorType() const;
+            
         private:
-            FunctionType FunctionType;
+            // The operator of this expression.
+            OperatorType operatorType;
         };
     }
 }
diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
index 5a1a470ce..7aa32a859 100644
--- a/src/storage/expressions/Valuation.h
+++ b/src/storage/expressions/Valuation.h
@@ -5,10 +5,34 @@
 
 namespace storm {
     namespace expressions {
+        /*!
+         * The base class of all valuations where a valuation assigns a concrete value to all identifiers. This is, for
+         * example, used for evaluating expressions.
+         */
         class Valuation {
         public:
+            /*!
+             * Retrieves the boolean value of the identifier with the given name.
+             *
+             * @param name The name of the boolean identifier whose value to retrieve.
+             * @return The value of the boolean identifier.
+             */
             virtual bool getBooleanValue(std::string const& name) const = 0;
+            
+            /*!
+             * Retrieves the integer value of the identifier with the given name.
+             *
+             * @param name The name of the integer identifier whose value to retrieve.
+             * @return The value of the integer identifier.
+             */
             virtual int_fast64_t getIntegerValue(std::string const& name) const = 0;
+            
+            /*!
+             * Retrieves the double value of the identifier with the given name.
+             *
+             * @param name The name of the double identifier whose value to retrieve.
+             * @return The value of the double identifier.
+             */
             virtual double getDoubleValue(std::string const& name) const = 0;
         };
     }
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
index 7b64707fd..6cc96f799 100644
--- a/src/storage/expressions/VariableExpression.cpp
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -12,47 +12,38 @@ namespace storm {
         }
         
         int_fast64_t VariableExpression::evaluateAsInt(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::int_), "Cannot evaluate expression as integer: return type is not an integer.");
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::Int), "Cannot evaluate expression as integer: return type is not an integer.");
             return evaluation.getIntegerValue(this->getVariableName());
         }
         
         bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::bool_), "Cannot evaluate expression as integer: return type is not a boolean.");
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::Bool), "Cannot evaluate expression as integer: return type is not a boolean.");
             return evaluation.getBooleanValue(this->getVariableName());
         }
         
         double VariableExpression::evaluateAsDouble(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::double_), "Cannot evaluate expression as integer: return type is not a double.");
+            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::Double), "Cannot evaluate expression as integer: return type is not a double.");
             return evaluation.getDoubleValue(this->getVariableName());
         }
         
-        std::unique_ptr<BaseExpression> VariableExpression::operator+(BaseExpression const& other) const {
-            // FIXME
-            return nullptr;
+        std::set<std::string> VariableExpression::getVariables() const {
+            return {this->getVariableName()};
         }
         
-        std::unique_ptr<BaseExpression> operator-(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> operator-() const;
-        std::unique_ptr<BaseExpression> operator*(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> operator/(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> operator&(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> operator|(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> operator~() const;
+        std::set<std::string> VariableExpression::getConstants() const {
+            return std::set<std::string>();
+        }
         
-        std::unique_ptr<BaseExpression> equals(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> notEquals(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> greater(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> greaterOrEqual(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> less(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> lessOrEqual(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> minimum(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> maximum(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> mod(BaseExpression const& other) const;
-        std::unique_ptr<BaseExpression> floor() const;
-        std::unique_ptr<BaseExpression> ceil() const;
+        std::unique_ptr<BaseExpression> VariableExpression::simplify() const {
+            return this->clone();
+        }
         
-        void visit(ExpressionVisitor* visitor) const;
+        void VariableExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
         
-        virtual std::unique_ptr<BaseExpression> clonse() const;
+        std::unique_ptr<BaseExpression> VariableExpression::clone() const {
+            return std::unique_ptr<BaseExpression>(new VariableExpression(*this));
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index d4d57907b..5aa89e4ce 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -7,40 +7,33 @@ namespace storm {
     namespace expressions {
         class VariableExpression : public BaseExpression {
             VariableExpression(ExpressionReturnType returnType, std::string const& variableName);
-            virtual ~VariableExpression() = default;
             
+            // Instantiate constructors and assignments with their default implementations.
+            VariableExpression(VariableExpression const&) = default;
+            VariableExpression(VariableExpression&&) = default;
+            VariableExpression& operator=(VariableExpression const&) = default;
+            VariableExpression& operator=(VariableExpression&&) = default;
+            virtual ~VariableExpression() = default;
+
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::unique_ptr<BaseExpression> clone() const override;
+
+            /*!
+             * Retrieves the name of the variable associated with this expression.
+             *
+             * @return The name of the variable.
+             */
             std::string const& getVariableName() const;
-            
-            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const;
-            virtual bool evaluateAsBool(Valuation const& evaluation) const;
-            virtual double evaluateAsDouble(Valuation const& evaluation) const;
-            
-            virtual std::unique_ptr<BaseExpression> operator+(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> operator-(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> operator-() const;
-            virtual std::unique_ptr<BaseExpression> operator*(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> operator/(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> operator&(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> operator|(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> operator~() const;
-            
-            virtual std::unique_ptr<BaseExpression> equals(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> notEquals(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> greater(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> greaterOrEqual(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> less(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> lessOrEqual(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> minimum(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> maximum(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> mod(BaseExpression const& other) const;
-            virtual std::unique_ptr<BaseExpression> floor() const;
-            virtual std::unique_ptr<BaseExpression> ceil() const;
-            
-            virtual void visit(ExpressionVisitor* visitor) const;
-            
-            virtual std::unique_ptr<BaseExpression> clonse() const;
-            
+
         private:
+            // The variable name associated with this expression.
             std::string variableName;
         };
     }

From 8af52c8866de4fecef60636f85de999ffb4f0528 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 6 Apr 2014 00:14:33 +0200
Subject: [PATCH 057/147] Finished new expression classes and corresponding
 functional tests.

Former-commit-id: 9268eab3a9ec3f818b672690acb720b7b70cd50c
---
 src/exceptions/ExceptionMacros.h              |  16 +-
 src/exceptions/InvalidOperationException.h    |  17 +
 src/exceptions/InvalidTypeException.h         |  18 +
 src/storage/expressions/BaseExpression.cpp    |  20 +-
 src/storage/expressions/BaseExpression.h      |  33 +-
 .../BinaryBooleanFunctionExpression.cpp       |  29 +-
 .../BinaryBooleanFunctionExpression.h         |  11 +-
 src/storage/expressions/BinaryExpression.cpp  |  20 +-
 src/storage/expressions/BinaryExpression.h    |  18 +-
 .../BinaryNumericalFunctionExpression.cpp     |  37 +-
 .../BinaryNumericalFunctionExpression.h       |  11 +-
 .../expressions/BinaryRelationExpression.cpp  |  35 +-
 .../expressions/BinaryRelationExpression.h    |  11 +-
 .../expressions/BooleanConstantExpression.cpp |   8 +-
 .../expressions/BooleanConstantExpression.h   |   6 +-
 .../expressions/BooleanLiteralExpression.cpp  |  18 +-
 .../expressions/BooleanLiteralExpression.h    |   9 +-
 .../expressions/ConstantExpression.cpp        |   8 +-
 src/storage/expressions/ConstantExpression.h  |   5 +-
 .../expressions/DoubleConstantExpression.cpp  |   4 +-
 .../expressions/DoubleConstantExpression.h    |   6 +-
 .../expressions/DoubleLiteralExpression.cpp   |  18 +-
 .../expressions/DoubleLiteralExpression.h     |  11 +-
 src/storage/expressions/Expression.cpp        | 213 ++++++++++-
 src/storage/expressions/Expression.h          | 151 ++++++--
 src/storage/expressions/ExpressionVisitor.h   |   1 +
 .../expressions/IntegerConstantExpression.cpp |   6 +-
 .../expressions/IntegerConstantExpression.h   |   6 +-
 .../expressions/IntegerLiteralExpression.cpp  |  18 +-
 .../expressions/IntegerLiteralExpression.h    |   9 +-
 src/storage/expressions/SimpleValuation.cpp   |  26 +-
 src/storage/expressions/SimpleValuation.h     |   3 +
 .../expressions/SubstitutionVisitor.cpp       | 170 ++++++++-
 src/storage/expressions/SubstitutionVisitor.h |  41 +-
 .../UnaryBooleanFunctionExpression.cpp        |  26 +-
 .../UnaryBooleanFunctionExpression.h          |  12 +-
 src/storage/expressions/UnaryExpression.cpp   |  18 +-
 src/storage/expressions/UnaryExpression.h     |  10 +-
 .../UnaryNumericalFunctionExpression.cpp      |  31 +-
 .../UnaryNumericalFunctionExpression.h        |  12 +-
 .../expressions/VariableExpression.cpp        |  33 +-
 src/storage/expressions/VariableExpression.h  |  14 +-
 test/functional/storage/ExpressionTest.cpp    | 357 +++++++++++++++++-
 43 files changed, 1287 insertions(+), 239 deletions(-)
 create mode 100644 src/exceptions/InvalidOperationException.h
 create mode 100644 src/exceptions/InvalidTypeException.h

diff --git a/src/exceptions/ExceptionMacros.h b/src/exceptions/ExceptionMacros.h
index dabfe25cb..09e7058ec 100644
--- a/src/exceptions/ExceptionMacros.h
+++ b/src/exceptions/ExceptionMacros.h
@@ -16,16 +16,16 @@ extern log4cplus::Logger logger;
         assert(cond);                           \
     }                                           \
 } while (false)
-#define LOG_THROW(cond, exception, message)     \
-{                                               \
-    if (!(cond)) {                              \
-        LOG4CPLUS_ERROR(logger, message);       \
-        throw exception() << message;           \
-    }                                           \
-} while (false)
 #else
 #define LOG_ASSERT(cond, message) /* empty */
-#define LOG_THROW(cond, exception, message) /* empty */
 #endif
 
+#define LOG_THROW(cond, exception, message)     \
+{                                               \
+if (!(cond)) {                              \
+LOG4CPLUS_ERROR(logger, message);       \
+throw exception() << message;           \
+}                                           \
+} while (false)
+
 #endif /* STORM_EXCEPTIONS_EXCEPTIONMACROS_H_ */
\ No newline at end of file
diff --git a/src/exceptions/InvalidOperationException.h b/src/exceptions/InvalidOperationException.h
new file mode 100644
index 000000000..728f7ff1c
--- /dev/null
+++ b/src/exceptions/InvalidOperationException.h
@@ -0,0 +1,17 @@
+#ifndef STORM_EXCEPTIONS_INVALIDOPERATIONEXCEPTION_H_
+#define STORM_EXCEPTIONS_INVALIDOPERATIONEXCEPTION_H_
+
+#include "src/exceptions/BaseException.h"
+
+namespace storm {
+    
+    namespace exceptions {
+        
+        /*!
+         * @brief This exception is thrown when an operation is invalid in this context
+         */
+        STORM_EXCEPTION_DEFINE_NEW(InvalidOperationException)
+        
+    } // namespace exceptions
+} // namespace storm
+#endif // STORM_EXCEPTIONS_INVALIDOPERATIONEXCEPTION_H_
diff --git a/src/exceptions/InvalidTypeException.h b/src/exceptions/InvalidTypeException.h
new file mode 100644
index 000000000..de2874218
--- /dev/null
+++ b/src/exceptions/InvalidTypeException.h
@@ -0,0 +1,18 @@
+#ifndef STORM_EXCEPTIONS_INVALIDTYPEEXCEPTION_H_
+#define STORM_EXCEPTIONS_INVALIDTYPEEXCEPTION_H_
+
+#include "src/exceptions/BaseException.h"
+
+namespace storm {
+    
+    namespace exceptions {
+        
+        /*!
+         * @brief This exception is thrown when a type is invalid in this context
+         */
+        STORM_EXCEPTION_DEFINE_NEW(InvalidTypeException)
+        
+    } // namespace exceptions
+    
+} // namespace storm
+#endif // STORM_EXCEPTIONS_INVALIDTYPEEXCEPTION_H_
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index ca2db09f1..200b8ac0f 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -1,5 +1,6 @@
 #include "src/storage/expressions/BaseExpression.h"
 #include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
 
 namespace storm {
     namespace expressions {        
@@ -11,6 +12,10 @@ namespace storm {
             return this->returnType;
         }
         
+        bool BaseExpression::hasIntegralReturnType() const {
+            return this->getReturnType() == ExpressionReturnType::Int;
+        }
+        
         bool BaseExpression::hasNumericalReturnType() const {
             return this->getReturnType() == ExpressionReturnType::Double || this->getReturnType() == ExpressionReturnType::Int;
         }
@@ -20,15 +25,15 @@ namespace storm {
         }
         
         int_fast64_t BaseExpression::evaluateAsInt(Valuation const& evaluation) const {
-            LOG_ASSERT(false, "Unable to evaluate expression as integer.");
+            LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
         }
         
         bool BaseExpression::evaluateAsBool(Valuation const& evaluation) const {
-            LOG_ASSERT(false, "Unable to evaluate expression as boolean.");
+            LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
         }
         
         double BaseExpression::evaluateAsDouble(Valuation const& evaluation) const {
-            LOG_ASSERT(false, "Unable to evaluate expression as double.");
+            LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
         }
         
         bool BaseExpression::isConstant() const {
@@ -42,5 +47,14 @@ namespace storm {
         bool BaseExpression::isFalse() const {
             return false;
         }
+        
+        std::shared_ptr<BaseExpression const> BaseExpression::getSharedPointer() const {
+            return this->shared_from_this();
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, BaseExpression const& expression) {
+            expression.printToStream(stream);
+            return stream;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 0698278da..7ca9e63ad 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -4,6 +4,7 @@
 #include <cstdint>
 #include <memory>
 #include <set>
+#include <iostream>
 
 #include "src/storage/expressions/Valuation.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
@@ -19,7 +20,7 @@ namespace storm {
         /*!
          * The base class of all expression classes.
          */
-        class BaseExpression {
+        class BaseExpression : public std::enable_shared_from_this<BaseExpression> {
         public:
             /*!
              * Constructs a base expression with the given return type.
@@ -107,7 +108,7 @@ namespace storm {
              *
              * @return A pointer to the simplified expression.
              */
-            virtual std::unique_ptr<BaseExpression> simplify() const = 0;
+            virtual std::shared_ptr<BaseExpression const> simplify() const = 0;
             
             /*!
              * Accepts the given visitor by calling its visit method.
@@ -117,18 +118,18 @@ namespace storm {
             virtual void accept(ExpressionVisitor* visitor) const = 0;
             
             /*!
-             * Performs a deep-copy of the expression.
+             * Retrieves whether the expression has a numerical return type, i.e., integer or double.
              *
-             * @return A pointer to a deep-copy of the expression.
+             * @return True iff the expression has a numerical return type.
              */
-            virtual std::unique_ptr<BaseExpression> clone() const = 0;
+            bool hasNumericalReturnType() const;
             
             /*!
-             * Retrieves whether the expression has a numerical return type, i.e., integer or double.
+             * Retrieves whether the expression has an integral return type, i.e., integer.
              *
-             * @return True iff the expression has a numerical return type.
+             * @return True iff the expression has an integral return type.
              */
-            bool hasNumericalReturnType() const;
+            bool hasIntegralReturnType() const;
             
             /*!
              * Retrieves whether the expression has a boolean return type.
@@ -137,6 +138,13 @@ namespace storm {
              */
             bool hasBooleanReturnType() const;
             
+            /*!
+             * Retrieves a shared pointer to this expression.
+             *
+             * @return A shared pointer to this expression.
+             */
+            std::shared_ptr<BaseExpression const> getSharedPointer() const;
+            
             /*!
              * Retrieves the return type of the expression.
              *
@@ -144,6 +152,15 @@ namespace storm {
              */
             ExpressionReturnType getReturnType() const;
             
+            friend std::ostream& operator<<(std::ostream& stream, BaseExpression const& expression);
+        protected:
+            /*!
+             * Prints the expression to the given stream.
+             *
+             * @param stream The stream to which to write the expression.
+             */
+            virtual void printToStream(std::ostream& stream) const = 0;
+            
         private:
             // The return type of this expression.
             ExpressionReturnType returnType;
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index e4034794e..8f5abf57c 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -1,8 +1,11 @@
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
+
 namespace storm {
     namespace expressions {
-        BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), operatorType(operatorType) {
+        BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, firstOperand, secondOperand), operatorType(operatorType) {
             // Intentionally left empty.
         }
         
@@ -11,6 +14,8 @@ namespace storm {
         }
         
         bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
+            LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
+            
             bool firstOperandEvaluation = this->getFirstOperand()->evaluateAsBool(valuation);
             bool secondOperandEvaluation = this->getSecondOperand()->evaluateAsBool(valuation);
             
@@ -23,9 +28,9 @@ namespace storm {
             return result;
         }
         
-        std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::simplify() const {
-            std::unique_ptr<BaseExpression> firstOperandSimplified = this->getFirstOperand()->simplify();
-            std::unique_ptr<BaseExpression> secondOperandSimplified = this->getSecondOperand()->simplify();
+        std::shared_ptr<BaseExpression const> BinaryBooleanFunctionExpression::simplify() const {
+            std::shared_ptr<BaseExpression const> firstOperandSimplified = this->getFirstOperand()->simplify();
+            std::shared_ptr<BaseExpression const> secondOperandSimplified = this->getSecondOperand()->simplify();
             
             switch (this->getOperatorType()) {
                 case OperatorType::And: if (firstOperandSimplified->isTrue()) {
@@ -49,15 +54,25 @@ namespace storm {
                 }
             }
             
-            return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getReturnType(), std::move(firstOperandSimplified), std::move(secondOperandSimplified), this->getOperatorType()));
+            // If the two successors remain unchanged, we can return a shared_ptr to this very object.
+            if (firstOperandSimplified.get() == this->getFirstOperand().get() && secondOperandSimplified.get() == this->getSecondOperand().get()) {
+                return this->shared_from_this();
+            } else {
+                return std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getReturnType(), firstOperandSimplified, secondOperandSimplified, this->getOperatorType()));
+            }
         }
         
         void BinaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(*this));
+        void BinaryBooleanFunctionExpression::printToStream(std::ostream& stream) const {
+            stream << "(" << *this->getFirstOperand();
+            switch (this->getOperatorType()) {
+                case OperatorType::And: stream << " && "; break;
+                case OperatorType::Or: stream << " || "; break;
+            }
+            stream << *this->getSecondOperand() << ")";
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index eaabd1d56..41ae92b7b 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -20,7 +20,7 @@ namespace storm {
              * @param secondOperand The second operand of the expression.
              * @param functionType The operator of the expression.
              */
-            BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& fistOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType);
+            BinaryBooleanFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, OperatorType operatorType);
             
             // Instantiate constructors and assignments with their default implementations.
             BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other) = default;
@@ -31,10 +31,9 @@ namespace storm {
             
             // Override base class methods.
             virtual bool evaluateAsBool(Valuation const& valuation) const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
-            
+
             /*!
              * Retrieves the operator associated with the expression.
              *
@@ -42,6 +41,10 @@ namespace storm {
              */
             OperatorType getOperatorType() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The operator of the expression.
             OperatorType operatorType;
diff --git a/src/storage/expressions/BinaryExpression.cpp b/src/storage/expressions/BinaryExpression.cpp
index 9038aca41..cfd18447c 100644
--- a/src/storage/expressions/BinaryExpression.cpp
+++ b/src/storage/expressions/BinaryExpression.cpp
@@ -2,22 +2,10 @@
 
 namespace storm {
     namespace expressions {
-        BinaryExpression::BinaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand) : BaseExpression(returnType), firstOperand(std::move(firstOperand)), secondOperand(std::move(secondOperand)) {
+        BinaryExpression::BinaryExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand) : BaseExpression(returnType), firstOperand(firstOperand), secondOperand(secondOperand) {
             // Intentionally left empty.
         }
-        
-        BinaryExpression::BinaryExpression(BinaryExpression const& other) : BaseExpression(other.getReturnType()), firstOperand(other.getFirstOperand()->clone()), secondOperand(other.getSecondOperand()->clone()) {
-            // Intentionally left empty.
-        }
-        
-        BinaryExpression& BinaryExpression::operator=(BinaryExpression const& other) {
-            if (this != &other) {
-                this->firstOperand = other.getFirstOperand()->clone();
-                this->secondOperand = other.getSecondOperand()->clone();
-            }
-            return *this;
-        }
-        
+                
         bool BinaryExpression::isConstant() const {
             return this->getFirstOperand()->isConstant() && this->getSecondOperand()->isConstant();
         }
@@ -36,11 +24,11 @@ namespace storm {
             return firstConstantSet;
         }
         
-        std::unique_ptr<BaseExpression> const& BinaryExpression::getFirstOperand() const {
+        std::shared_ptr<BaseExpression const> const& BinaryExpression::getFirstOperand() const {
             return this->firstOperand;
         }
         
-        std::unique_ptr<BaseExpression> const& BinaryExpression::getSecondOperand() const {
+        std::shared_ptr<BaseExpression const> const& BinaryExpression::getSecondOperand() const {
             return this->secondOperand;
         }
     }
diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h
index a94513cb5..fd1b1903a 100644
--- a/src/storage/expressions/BinaryExpression.h
+++ b/src/storage/expressions/BinaryExpression.h
@@ -17,13 +17,11 @@ namespace storm {
              * @param firstOperand The first operand of the expression.
              * @param secondOperand The second operand of the expression.
              */
-            BinaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand);
+            BinaryExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand);
             
-            // Provide custom versions of copy construction and assignment.
-            BinaryExpression(BinaryExpression const& other);
-            BinaryExpression& operator=(BinaryExpression const& other);
-
-            // Create default variants of move construction/assignment and virtual destructor.
+            // Instantiate constructors and assignments with their default implementations.
+            BinaryExpression(BinaryExpression const& other) = default;
+            BinaryExpression& operator=(BinaryExpression const& other) = default;
             BinaryExpression(BinaryExpression&&) = default;
             BinaryExpression& operator=(BinaryExpression&&) = default;
             virtual ~BinaryExpression() = default;
@@ -38,21 +36,21 @@ namespace storm {
              *
              * @return The first operand of the expression.
              */
-            std::unique_ptr<BaseExpression> const& getFirstOperand() const;
+            std::shared_ptr<BaseExpression const> const& getFirstOperand() const;
             
             /*!
              * Retrieves the second operand of the expression.
              *
              * @return The second operand of the expression.
              */
-            std::unique_ptr<BaseExpression> const& getSecondOperand() const;
+            std::shared_ptr<BaseExpression const> const& getSecondOperand() const;
 
         private:
             // The first operand of the expression.
-            std::unique_ptr<BaseExpression> firstOperand;
+            std::shared_ptr<BaseExpression const> firstOperand;
             
             // The second operand of the expression.
-            std::unique_ptr<BaseExpression> secondOperand;
+            std::shared_ptr<BaseExpression const> secondOperand;
         };
     }
 }
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
index 7139db695..521e554bb 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -2,15 +2,21 @@
 
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
 
 namespace storm {
     namespace expressions {
-        BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), operatorType(operatorType) {
+        BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, OperatorType operatorType) : BinaryExpression(returnType, firstOperand, secondOperand), operatorType(operatorType) {
             // Intentionally left empty.
         }
         
+        BinaryNumericalFunctionExpression::OperatorType BinaryNumericalFunctionExpression::getOperatorType() const {
+            return this->operatorType;
+        }
+        
         int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
-            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::Int, "Unable to evaluate expression as integer.");
+            LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
+            
             int_fast64_t firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation);
             int_fast64_t secondOperandEvaluation = this->getSecondOperand()->evaluateAsInt(valuation);
             switch (this->getOperatorType()) {
@@ -24,7 +30,8 @@ namespace storm {
         }
         
         double BinaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
-            LOG_ASSERT(this->getReturnType() == ExpressionReturnType::Double, "Unable to evaluate expression as double.");
+            LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
+            
             double firstOperandEvaluation = this->getFirstOperand()->evaluateAsDouble(valuation);
             double secondOperandEvaluation = this->getSecondOperand()->evaluateAsDouble(valuation);
             switch (this->getOperatorType()) {
@@ -37,16 +44,32 @@ namespace storm {
             }
         }
         
-        std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::simplify() const {
-            return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType(), this->getFirstOperand()->simplify(), this->getSecondOperand()->simplify(), this->getOperatorType()));
+        std::shared_ptr<BaseExpression const> BinaryNumericalFunctionExpression::simplify() const {
+            std::shared_ptr<BaseExpression const> firstOperandSimplified = this->getFirstOperand()->simplify();
+            std::shared_ptr<BaseExpression const> secondOperandSimplified = this->getSecondOperand()->simplify();
+            
+            if (firstOperandSimplified.get() == this->getFirstOperand().get() && secondOperandSimplified.get() == this->getSecondOperand().get()) {
+                return this->shared_from_this();
+            } else {
+                return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType(), firstOperandSimplified, secondOperandSimplified, this->getOperatorType()));
+            }
         }
         
         void BinaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(*this));
+        void BinaryNumericalFunctionExpression::printToStream(std::ostream& stream) const {
+            stream << "(";
+            switch (this->getOperatorType()) {
+                case OperatorType::Plus: stream << *this->getFirstOperand() << " + " << *this->getSecondOperand(); break;
+                case OperatorType::Minus: stream << *this->getFirstOperand() << " - " << *this->getSecondOperand(); break;
+                case OperatorType::Times: stream << *this->getFirstOperand() << " * " << *this->getSecondOperand(); break;
+                case OperatorType::Divide: stream << *this->getFirstOperand() << " / " << *this->getSecondOperand(); break;
+                case OperatorType::Min: stream << "min(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break;
+                case OperatorType::Max: stream << "max(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break;
+            }
+            stream << ")";
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
index 92d4bc0d2..8d49e541a 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -20,7 +20,7 @@ namespace storm {
              * @param secondOperand The second operand of the expression.
              * @param functionType The operator of the expression.
              */
-            BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, OperatorType operatorType);
+            BinaryNumericalFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, OperatorType operatorType);
             
             // Instantiate constructors and assignments with their default implementations.
             BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other) = default;
@@ -32,10 +32,9 @@ namespace storm {
             // Override base class methods.
             virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
             virtual double evaluateAsDouble(Valuation const& valuation) const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
-            
+
             /*!
              * Retrieves the operator associated with the expression.
              *
@@ -43,6 +42,10 @@ namespace storm {
              */
             OperatorType getOperatorType() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The operator of the expression.
             OperatorType operatorType;
diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp
index fb4123fca..e23df77c4 100644
--- a/src/storage/expressions/BinaryRelationExpression.cpp
+++ b/src/storage/expressions/BinaryRelationExpression.cpp
@@ -1,12 +1,17 @@
 #include "src/storage/expressions/BinaryRelationExpression.h"
 
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
+
 namespace storm {
     namespace expressions {
-        BinaryRelationExpression::BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, RelationType relationType) : BinaryExpression(returnType, std::move(firstOperand), std::move(secondOperand)), relationType(relationType) {
+        BinaryRelationExpression::BinaryRelationExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, RelationType relationType) : BinaryExpression(returnType, firstOperand, secondOperand), relationType(relationType) {
             // Intentionally left empty.
         }
                 
         bool BinaryRelationExpression::evaluateAsBool(Valuation const& valuation) const {
+            LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
+
             double firstOperandEvaluated = this->getFirstOperand()->evaluateAsDouble(valuation);
             double secondOperandEvaluated = this->getSecondOperand()->evaluateAsDouble(valuation);
             switch (this->getRelationType()) {
@@ -19,20 +24,36 @@ namespace storm {
             }
         }
         
-        std::unique_ptr<BaseExpression> BinaryRelationExpression::simplify() const {
-            return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(this->getReturnType(), this->getFirstOperand()->simplify(), this->getSecondOperand()->simplify(), this->getRelationType()));
+        std::shared_ptr<BaseExpression const> BinaryRelationExpression::simplify() const {
+            std::shared_ptr<BaseExpression const> firstOperandSimplified = this->getFirstOperand()->simplify();
+            std::shared_ptr<BaseExpression const> secondOperandSimplified = this->getSecondOperand()->simplify();
+            
+            if (firstOperandSimplified.get() == this->getFirstOperand().get() && secondOperandSimplified.get() == this->getSecondOperand().get()) {
+                return this->shared_from_this();
+            } else {
+                return std::shared_ptr<BaseExpression>(new BinaryRelationExpression(this->getReturnType(), firstOperandSimplified, secondOperandSimplified, this->getRelationType()));
+            }
         }
         
         void BinaryRelationExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> BinaryRelationExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(*this));
-        }
-        
         BinaryRelationExpression::RelationType BinaryRelationExpression::getRelationType() const {
             return this->relationType;
         }
+        
+        void BinaryRelationExpression::printToStream(std::ostream& stream) const {
+            stream << "(" << *this->getFirstOperand();
+            switch (this->getRelationType()) {
+                case RelationType::Equal: stream << " == "; break;
+                case RelationType::NotEqual: stream << " != "; break;
+                case RelationType::Greater: stream << " > "; break;
+                case RelationType::GreaterOrEqual: stream << " >= "; break;
+                case RelationType::Less: stream << " < "; break;
+                case RelationType::LessOrEqual: stream << " <= "; break;
+            }
+            stream << *this->getSecondOperand() << ")";
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h
index 31145ec30..70201313c 100644
--- a/src/storage/expressions/BinaryRelationExpression.h
+++ b/src/storage/expressions/BinaryRelationExpression.h
@@ -20,7 +20,7 @@ namespace storm {
              * @param secondOperand The second operand of the expression.
              * @param relationType The operator of the expression.
              */
-            BinaryRelationExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& firstOperand, std::unique_ptr<BaseExpression>&& secondOperand, RelationType relationType);
+            BinaryRelationExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, RelationType relationType);
             
             // Instantiate constructors and assignments with their default implementations.
             BinaryRelationExpression(BinaryRelationExpression const& other) = default;
@@ -31,10 +31,9 @@ namespace storm {
             
             // Override base class methods.
             virtual bool evaluateAsBool(Valuation const& valuation) const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
-            
+
             /*!
              * Retrieves the relation associated with the expression.
              *
@@ -42,6 +41,10 @@ namespace storm {
              */
             RelationType getRelationType() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The relation type of the expression.
             RelationType relationType;
diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp
index c20d8a8b7..b3b453097 100644
--- a/src/storage/expressions/BooleanConstantExpression.cpp
+++ b/src/storage/expressions/BooleanConstantExpression.cpp
@@ -10,12 +10,12 @@ namespace storm {
             return valuation.getBooleanValue(this->getConstantName());
         }
         
-        std::unique_ptr<BaseExpression> BooleanConstantExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new BooleanConstantExpression(*this));
-        }
-        
         void BooleanConstantExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
+        
+        std::shared_ptr<BaseExpression const> BooleanConstantExpression::simplify() const {
+            return this->shared_from_this();
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
index 7b72fdc4e..d239f146d 100644
--- a/src/storage/expressions/BooleanConstantExpression.h
+++ b/src/storage/expressions/BooleanConstantExpression.h
@@ -22,9 +22,9 @@ namespace storm {
             virtual ~BooleanConstantExpression() = default;
             
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const;
-            virtual std::unique_ptr<BaseExpression> clone() const;
-            virtual void accept(ExpressionVisitor* visitor) const;
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
         };
     }
 }
diff --git a/src/storage/expressions/BooleanLiteralExpression.cpp b/src/storage/expressions/BooleanLiteralExpression.cpp
index 371e9f7e9..7fb01cec4 100644
--- a/src/storage/expressions/BooleanLiteralExpression.cpp
+++ b/src/storage/expressions/BooleanLiteralExpression.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace expressions {
-        BooleanLiteralExpression::BooleanLiteralExpression(bool value) : value(value) {
+        BooleanLiteralExpression::BooleanLiteralExpression(bool value) : BaseExpression(ExpressionReturnType::Bool), value(value) {
             // Intentionally left empty.
         }
         
@@ -23,27 +23,27 @@ namespace storm {
         }
         
         std::set<std::string> BooleanLiteralExpression::getVariables() const {
-            return {};
+            return std::set<std::string>();
         }
         
         std::set<std::string> BooleanLiteralExpression::getConstants() const {
-            return {};
+            return std::set<std::string>();
         }
         
-        std::unique_ptr<BaseExpression> BooleanLiteralExpression::simplify() const {
-            return this->clone();
+        std::shared_ptr<BaseExpression const> BooleanLiteralExpression::simplify() const {
+            return this->shared_from_this();
         }
         
         void BooleanLiteralExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> BooleanLiteralExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(*this));
-        }
-        
         bool BooleanLiteralExpression::getValue() const {
             return this->value;
         }
+        
+        void BooleanLiteralExpression::printToStream(std::ostream& stream) const {
+            stream << (this->getValue() ? "true" : "false");
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanLiteralExpression.h b/src/storage/expressions/BooleanLiteralExpression.h
index 837190c95..1c7baed09 100644
--- a/src/storage/expressions/BooleanLiteralExpression.h
+++ b/src/storage/expressions/BooleanLiteralExpression.h
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace expressions {
-        class BooleanLiteralExpression : BaseExpression {
+        class BooleanLiteralExpression : public BaseExpression {
         public:
             /*!
              * Creates a boolean literal expression with the given value.
@@ -28,9 +28,8 @@ namespace storm {
             virtual bool isFalse() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
             
             /*!
              * Retrieves the value of the boolean literal.
@@ -39,6 +38,10 @@ namespace storm {
              */
             bool getValue() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+            
         private:
             // The value of the boolean literal.
             bool value;
diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp
index 08bd26a95..d09a75573 100644
--- a/src/storage/expressions/ConstantExpression.cpp
+++ b/src/storage/expressions/ConstantExpression.cpp
@@ -14,12 +14,12 @@ namespace storm {
             return {this->getConstantName()};
         }
         
-        std::unique_ptr<BaseExpression> ConstantExpression::simplify() const {
-            return this->clone();
-        }
-        
         std::string const& ConstantExpression::getConstantName() const {
             return this->constantName;
         }
+        
+        void ConstantExpression::printToStream(std::ostream& stream) const {
+            stream << this->getConstantName();
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
index b8b985ac2..70ccf6b35 100644
--- a/src/storage/expressions/ConstantExpression.h
+++ b/src/storage/expressions/ConstantExpression.h
@@ -25,7 +25,6 @@ namespace storm {
             // Override base class methods.
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
             
             /*!
              * Retrieves the name of the constant.
@@ -33,6 +32,10 @@ namespace storm {
              * @return The name of the constant.
              */
             std::string const& getConstantName() const;
+
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
             
         private:
             // The name of the constant.
diff --git a/src/storage/expressions/DoubleConstantExpression.cpp b/src/storage/expressions/DoubleConstantExpression.cpp
index c0c7925dc..d0f5a2799 100644
--- a/src/storage/expressions/DoubleConstantExpression.cpp
+++ b/src/storage/expressions/DoubleConstantExpression.cpp
@@ -10,8 +10,8 @@ namespace storm {
             return valuation.getDoubleValue(this->getConstantName());
         }
         
-        std::unique_ptr<BaseExpression> DoubleConstantExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new DoubleConstantExpression(*this));
+        std::shared_ptr<BaseExpression const> DoubleConstantExpression::simplify() const {
+            return this->shared_from_this();
         }
         
         void DoubleConstantExpression::accept(ExpressionVisitor* visitor) const {
diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h
index 28455190f..349de5216 100644
--- a/src/storage/expressions/DoubleConstantExpression.h
+++ b/src/storage/expressions/DoubleConstantExpression.h
@@ -22,9 +22,9 @@ namespace storm {
             virtual ~DoubleConstantExpression() = default;
             
             // Override base class methods.
-            virtual double evaluateAsDouble(Valuation const& valuation) const;
-            virtual std::unique_ptr<BaseExpression> clone() const;
-            virtual void accept(ExpressionVisitor* visitor) const;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
         };
     }
 }
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index a96bdcdd9..176823803 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace expressions {
-        DoubleLiteralExpression::DoubleLiteralExpression(double value) : value(value) {
+        DoubleLiteralExpression::DoubleLiteralExpression(double value) : BaseExpression(ExpressionReturnType::Double), value(value) {
             // Intentionally left empty.
         }
         
@@ -15,27 +15,27 @@ namespace storm {
         }
         
         std::set<std::string> DoubleLiteralExpression::getVariables() const {
-            return {};
+            return std::set<std::string>();
         }
         
         std::set<std::string> DoubleLiteralExpression::getConstants() const {
-            return {};
+            return std::set<std::string>();
         }
         
-        std::unique_ptr<BaseExpression> DoubleLiteralExpression::simplify() const {
-            return this->clone();
+        std::shared_ptr<BaseExpression const> DoubleLiteralExpression::simplify() const {
+            return this->shared_from_this();
         }
         
         void DoubleLiteralExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> DoubleLiteralExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new DoubleLiteralExpression(*this));
-        }
-        
         double DoubleLiteralExpression::getValue() const {
             return this->value;
         }
+        
+        void DoubleLiteralExpression::printToStream(std::ostream& stream) const {
+            stream << this->getValue();
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index b15e5e013..5d97e6b59 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace expressions {
-        class DoubleLiteralExpression : BaseExpression {
+        class DoubleLiteralExpression : public BaseExpression {
         public:
             /*!
              * Creates an double literal expression with the given value.
@@ -26,10 +26,9 @@ namespace storm {
             virtual bool isConstant() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
-            
+
             /*!
              * Retrieves the value of the double literal.
              *
@@ -37,6 +36,10 @@ namespace storm {
              */
             double getValue() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+            
         private:
             // The value of the double literal.
             double value;
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index c73108336..bd2e3cbc9 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -3,32 +3,229 @@
 
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/SubstitutionVisitor.h"
+#include "src/exceptions/InvalidTypeException.h"
+#include "src/exceptions/ExceptionMacros.h"
+
+#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/BinaryRelationExpression.h"
+#include "src/storage/expressions/BooleanConstantExpression.h"
+#include "src/storage/expressions/IntegerConstantExpression.h"
+#include "src/storage/expressions/DoubleConstantExpression.h"
+#include "src/storage/expressions/BooleanLiteralExpression.h"
+#include "src/storage/expressions/IntegerLiteralExpression.h"
+#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/VariableExpression.h"
+#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
 
 namespace storm {
     namespace expressions {
-        Expression::Expression(std::unique_ptr<BaseExpression>&& expressionPtr) : expressionPtr(std::move(expressionPtr)) {
+        Expression::Expression(std::shared_ptr<BaseExpression const> const& expressionPtr) : expressionPtr(expressionPtr) {
             // Intentionally left empty.
         }
         
         template<template<typename... Arguments> class MapType>
         Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const {
-            SubstitutionVisitor visitor;
-            return visitor.substitute<MapType>(this->getBaseExpressionPointer(), identifierToExpressionMap);
+            return SubstitutionVisitor<MapType>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
         }
-
-        Expression Expression::operator+(Expression const& other) {
-            return Expression(this->getBaseExpression() + other.getBaseExpression());
+        
+        bool Expression::evaluateAsBool(Valuation const& valuation) const {
+            return this->getBaseExpression().evaluateAsBool(valuation);
+        }
+        
+        int_fast64_t Expression::evaluateAsInt(Valuation const& valuation) const {
+            return this->getBaseExpression().evaluateAsInt(valuation);
+        }
+        
+        double Expression::evaluateAsDouble(Valuation const& valuation) const {
+            return this->getBaseExpression().evaluateAsDouble(valuation);
+        }
+        
+        Expression Expression::simplify() {
+            return Expression(this->getBaseExpression().simplify());
+        }
+        
+        bool Expression::isConstant() const {
+            return this->getBaseExpression().isConstant();
+        }
+        
+        bool Expression::isTrue() const {
+            return this->getBaseExpression().isTrue();
+        }
+        
+        bool Expression::isFalse() const {
+            return this->getBaseExpression().isFalse();
+        }
+        
+        std::set<std::string> Expression::getVariables() const {
+            return this->getBaseExpression().getVariables();
+        }
+        
+        std::set<std::string> Expression::getConstants() const {
+            return this->getBaseExpression().getConstants();
         }
         
         BaseExpression const& Expression::getBaseExpression() const {
             return *this->expressionPtr;
         }
         
-        BaseExpression const* Expression::getBaseExpressionPointer() const {
-            return this->expressionPtr.get();
+        std::shared_ptr<BaseExpression const> const& Expression::getBaseExpressionPointer() const {
+            return this->expressionPtr;
+        }
+        
+        ExpressionReturnType Expression::getReturnType() const {
+            return this->getBaseExpression().getReturnType();
+        }
+        
+        bool Expression::hasNumericalReturnType() const {
+            return this->getReturnType() == ExpressionReturnType::Int || this->getReturnType() == ExpressionReturnType::Double;
+        }
+        
+        bool Expression::hasBooleanReturnType() const {
+            return this->getReturnType() == ExpressionReturnType::Bool;
+        }
+        
+        Expression Expression::createBooleanLiteral(bool value) {
+            return Expression(std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(value)));
+        }
+        
+        Expression Expression::createTrue() {
+            return createBooleanLiteral(true);
+        }
+        
+        Expression Expression::createFalse() {
+            return createBooleanLiteral(false);
+        }
+        
+        Expression Expression::createIntegerLiteral(int_fast64_t value) {
+            return Expression(std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(value)));
+        }
+        
+        Expression Expression::createDoubleLiteral(double value) {
+            return Expression(std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(value)));
+        }
+        
+        Expression Expression::createBooleanVariable(std::string const& variableName) {
+            return Expression(std::shared_ptr<BaseExpression>(new VariableExpression(ExpressionReturnType::Bool, variableName)));
+        }
+        
+        Expression Expression::createIntegerVariable(std::string const& variableName) {
+            return Expression(std::shared_ptr<BaseExpression>(new VariableExpression(ExpressionReturnType::Int, variableName)));
+        }
+        
+        Expression Expression::createDoubleVariable(std::string const& variableName) {
+            return Expression(std::shared_ptr<BaseExpression>(new VariableExpression(ExpressionReturnType::Double, variableName)));
+        }
+        
+        Expression Expression::createBooleanConstant(std::string const& constantName) {
+            return Expression(std::shared_ptr<BaseExpression>(new BooleanConstantExpression(constantName)));
+        }
+        
+        Expression Expression::createIntegerConstant(std::string const& constantName) {
+            return Expression(std::shared_ptr<BaseExpression>(new IntegerConstantExpression(constantName)));
+        }
+        
+        Expression Expression::createDoubleConstant(std::string const& constantName) {
+            return Expression(std::shared_ptr<BaseExpression>(new DoubleConstantExpression(constantName)));
+        }
+        
+        Expression Expression::operator+(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '+' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Plus)));
+        }
+        
+        Expression Expression::operator-(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '-' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Minus)));
+        }
+        
+        Expression Expression::operator-() const {
+            LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '-' requires numerical operand.");
+            return Expression(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getReturnType(), this->getBaseExpressionPointer(), UnaryNumericalFunctionExpression::OperatorType::Minus)));
+        }
+        
+        Expression Expression::operator*(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '*' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Times)));
+        }
+        
+        Expression Expression::operator/(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '/' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Divide)));
+        }
+        
+        Expression Expression::operator&&(Expression const& other) const {
+            LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '&&' requires boolean operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::And)));
+        }
+        
+        Expression Expression::operator||(Expression const& other) const {
+            LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '||' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Or)));
+        }
+        
+        Expression Expression::operator!() const {
+            LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '!' requires boolean operand.");
+            return Expression(std::shared_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), UnaryBooleanFunctionExpression::OperatorType::Not)));
+        }
+        
+        Expression Expression::operator==(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '==' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::Equal)));
+        }
+        
+        Expression Expression::operator!=(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '!=' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::NotEqual)));
+        }
+        
+        Expression Expression::operator>(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '>' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::Greater)));
+        }
+        
+        Expression Expression::operator>=(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '>=' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::GreaterOrEqual)));
+        }
+        
+        Expression Expression::operator<(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '<' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::Less)));
+        }
+        
+        Expression Expression::operator<=(Expression const& other) const {
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '<=' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::LessOrEqual)));
+        }
+        
+        Expression Expression::minimum(Expression const& lhs, Expression const& rhs) {
+            LOG_THROW(lhs.hasNumericalReturnType() && rhs.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator 'min' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(lhs.getReturnType() == ExpressionReturnType::Int && rhs.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, lhs.getBaseExpressionPointer(), rhs.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Min)));
+        }
+        
+        Expression Expression::maximum(Expression const& lhs, Expression const& rhs) {
+            LOG_THROW(lhs.hasNumericalReturnType() && rhs.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator 'max' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(lhs.getReturnType() == ExpressionReturnType::Int && rhs.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, lhs.getBaseExpressionPointer(), rhs.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Max)));
+        }
+        
+        Expression Expression::floor() const {
+            LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator 'floor' requires numerical operand.");
+            return Expression(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(ExpressionReturnType::Int, this->getBaseExpressionPointer(), UnaryNumericalFunctionExpression::OperatorType::Floor)));
+        }
+        
+        Expression Expression::ceil() const {
+            LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator 'ceil' requires numerical operand.");
+            return Expression(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(ExpressionReturnType::Int, this->getBaseExpressionPointer(), UnaryNumericalFunctionExpression::OperatorType::Ceil)));
         }
         
         template Expression Expression::substitute<std::map>(std::map<std::string, storm::expressions::Expression> const&) const;
         template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, storm::expressions::Expression> const&) const;
+        
+        std::ostream& operator<<(std::ostream& stream, Expression const& expression) {
+            stream << expression.getBaseExpression();
+            return stream;
+        }
     }
 }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index c866d64cb..52e656a15 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -11,29 +11,53 @@ namespace storm {
         public:
             Expression() = default;
             
+            /*!
+             * Creates an expression with the given underlying base expression.
+             *
+             * @param expressionPtr A pointer to the underlying base expression.
+             */
+            Expression(std::shared_ptr<BaseExpression const> const& expressionPtr);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            Expression(Expression const& other) = default;
+            Expression& operator=(Expression const& other) = default;
+            Expression(Expression&&) = default;
+            Expression& operator=(Expression&&) = default;
+            
             // Static factory methods to create atomic expression parts.
+            static Expression createBooleanLiteral(bool value);
+            static Expression createTrue();
+            static Expression createFalse();
+            static Expression createIntegerLiteral(int_fast64_t value);
+            static Expression createDoubleLiteral(double value);
+            static Expression createBooleanVariable(std::string const& variableName);
+            static Expression createIntegerVariable(std::string const& variableName);
+            static Expression createDoubleVariable(std::string const& variableName);
+            static Expression createBooleanConstant(std::string const& constantName);
+            static Expression createIntegerConstant(std::string const& constantName);
+            static Expression createDoubleConstant(std::string const& constantName);
             
-            // Virtual operator overloading.
+            // Provide operator overloads to conveniently construct new expressions from other expressions.
             Expression operator+(Expression const& other) const;
             Expression operator-(Expression const& other) const;
             Expression operator-() const;
             Expression operator*(Expression const& other) const;
             Expression operator/(Expression const& other) const;
-            Expression operator&(Expression const& other) const;
-            Expression operator|(Expression const& other) const;
-            Expression operator~() const;
-            
-            Expression equals(Expression const& other) const;
-            Expression notEquals(Expression const& other) const;
-            Expression greater(Expression const& other) const;
-            Expression greaterOrEqual(Expression const& other) const;
-            Expression less(Expression const& other) const;
-            Expression lessOrEqual(Expression const& other) const;
-            Expression minimum(Expression const& other) const;
-            Expression maximum(Expression const& other) const;
-            Expression mod(Expression const& other) const;
+            Expression operator&&(Expression const& other) const;
+            Expression operator||(Expression const& other) const;
+            Expression operator!() const;
+            Expression operator==(Expression const& other) const;
+            Expression operator!=(Expression const& other) const;
+            Expression operator>(Expression const& other) const;
+            Expression operator>=(Expression const& other) const;
+            Expression operator<(Expression const& other) const;
+            Expression operator<=(Expression const& other) const;
+            
             Expression floor() const;
             Expression ceil() const;
+
+            static Expression minimum(Expression const& lhs, Expression const& rhs);
+            static Expression maximum(Expression const& lhs, Expression const& rhs);
             
             /*!
              * Substitutes all occurrences of identifiers according to the given map. Note that this substitution is
@@ -48,19 +72,76 @@ namespace storm {
             Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const;
             
             /*!
-             * Retrieves the return type of the expression.
+             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
+             * valuation and returns the resulting boolean value. If the return type of the expression is not a boolean
+             * an exception is thrown.
              *
-             * @return The return type of the expression.
+             * @param valuation The valuation of unknowns under which to evaluate the expression.
+             * @return The boolean value of the expression under the given valuation.
              */
-            ExpressionReturnType getReturnType() const;
+            bool evaluateAsBool(Valuation const& valuation) const;
             
-        private:
             /*!
-             * Creates an expression with the given underlying base expression.
+             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
+             * valuation and returns the resulting integer value. If the return type of the expression is not an integer
+             * an exception is thrown.
              *
-             * @param expressionPtr A pointer to the underlying base expression.
+             * @param valuation The valuation of unknowns under which to evaluate the expression.
+             * @return The integer value of the expression under the given valuation.
+             */
+            int_fast64_t evaluateAsInt(Valuation const& valuation) const;
+            
+            /*!
+             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
+             * valuation and returns the resulting double value. If the return type of the expression is not a double
+             * an exception is thrown.
+             *
+             * @param valuation The valuation of unknowns under which to evaluate the expression.
+             * @return The double value of the expression under the given valuation.
+             */
+            double evaluateAsDouble(Valuation const& valuation) const;
+            
+            /*!
+             * Simplifies the expression according to some basic rules.
+             *
+             * @return The simplified expression.
+             */
+            Expression simplify();
+            
+            /*!
+             * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants.
+             *
+             * @return True iff the expression is constant.
+             */
+            bool isConstant() const;
+            
+            /*!
+             * Checks if the expression is equal to the boolean literal true.
+             *
+             * @return True iff the expression is equal to the boolean literal true.
+             */
+            bool isTrue() const;
+            
+            /*!
+             * Checks if the expression is equal to the boolean literal false.
+             *
+             * @return True iff the expression is equal to the boolean literal false.
              */
-            Expression(std::unique_ptr<BaseExpression>&& expressionPtr);
+            bool isFalse() const;
+            
+            /*!
+             * Retrieves the set of all variables that appear in the expression.
+             *
+             * @return The set of all variables that appear in the expression.
+             */
+            std::set<std::string> getVariables() const;
+            
+            /*!
+             * Retrieves the set of all constants that appear in the expression.
+             *
+             * @return The set of all constants that appear in the expression.
+             */
+            std::set<std::string> getConstants() const;
             
             /*!
              * Retrieves the base expression underlying this expression object. Note that prior to calling this, the
@@ -75,10 +156,34 @@ namespace storm {
              *
              * @return A pointer to the underlying base expression.
              */
-            BaseExpression const* getBaseExpressionPointer() const;
+            std::shared_ptr<BaseExpression const> const& getBaseExpressionPointer() const;
+
+            /*!
+             * Retrieves the return type of the expression.
+             *
+             * @return The return type of the expression.
+             */
+            ExpressionReturnType getReturnType() const;
             
+            /*!
+             * Retrieves whether the expression has a numerical return type, i.e., integer or double.
+             *
+             * @return True iff the expression has a numerical return type.
+             */
+            bool hasNumericalReturnType() const;
+            
+            /*!
+             * Retrieves whether the expression has a boolean return type.
+             *
+             * @return True iff the expression has a boolean return type.
+             */
+            bool hasBooleanReturnType() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, Expression const& expression);
+
+        private:
             // A pointer to the underlying base expression.
-            std::unique_ptr<BaseExpression> expressionPtr;
+            std::shared_ptr<BaseExpression const> expressionPtr;
         };
     }
 }
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index 4bd2e8d29..8e6dca24e 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -19,6 +19,7 @@ namespace storm {
         class DoubleLiteralExpression;
         
         class ExpressionVisitor {
+        public:
             virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0;
             virtual void visit(BinaryRelationExpression const* expression) = 0;
diff --git a/src/storage/expressions/IntegerConstantExpression.cpp b/src/storage/expressions/IntegerConstantExpression.cpp
index 87e109423..92bedebc9 100644
--- a/src/storage/expressions/IntegerConstantExpression.cpp
+++ b/src/storage/expressions/IntegerConstantExpression.cpp
@@ -6,7 +6,7 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        int_fast64_t IntegerConstantExpression::evaluateAsInteger(Valuation const& valuation) const {
+        int_fast64_t IntegerConstantExpression::evaluateAsInt(Valuation const& valuation) const {
             return valuation.getIntegerValue(this->getConstantName());
         }
         
@@ -14,8 +14,8 @@ namespace storm {
             return static_cast<double>(valuation.getIntegerValue(this->getConstantName()));
         }
         
-        std::unique_ptr<BaseExpression> IntegerConstantExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new IntegerConstantExpression(*this));
+        std::shared_ptr<BaseExpression const> IntegerConstantExpression::simplify() const {
+            return this->shared_from_this();
         }
         
         void IntegerConstantExpression::accept(ExpressionVisitor* visitor) const {
diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h
index 402679163..05deaf49c 100644
--- a/src/storage/expressions/IntegerConstantExpression.h
+++ b/src/storage/expressions/IntegerConstantExpression.h
@@ -22,9 +22,9 @@ namespace storm {
             virtual ~IntegerConstantExpression() = default;
             
             // Override base class methods.
-            virtual int_fast64_t evaluateAsInteger(Valuation const& valuation) const;
-            virtual double evaluateAsDouble(Valuation const& valuation) const;
-            virtual std::unique_ptr<BaseExpression> clone() const;
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const;
         };
     }
diff --git a/src/storage/expressions/IntegerLiteralExpression.cpp b/src/storage/expressions/IntegerLiteralExpression.cpp
index ad74e58bd..16adeadc6 100644
--- a/src/storage/expressions/IntegerLiteralExpression.cpp
+++ b/src/storage/expressions/IntegerLiteralExpression.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace expressions {
-        IntegerLiteralExpression::IntegerLiteralExpression(int_fast64_t value) : value(value) {
+        IntegerLiteralExpression::IntegerLiteralExpression(int_fast64_t value) : BaseExpression(ExpressionReturnType::Int), value(value) {
             // Intentionally left empty.
         }
         
@@ -19,27 +19,27 @@ namespace storm {
         }
         
         std::set<std::string> IntegerLiteralExpression::getVariables() const {
-            return {};
+            return std::set<std::string>();
         }
         
         std::set<std::string> IntegerLiteralExpression::getConstants() const {
-            return {};
+            return std::set<std::string>();
         }
         
-        std::unique_ptr<BaseExpression> IntegerLiteralExpression::simplify() const {
-            return this->clone();
+        std::shared_ptr<BaseExpression const> IntegerLiteralExpression::simplify() const {
+            return this->shared_from_this();
         }
         
         void IntegerLiteralExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> IntegerLiteralExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new IntegerLiteralExpression(*this));
-        }
-        
         int_fast64_t IntegerLiteralExpression::getValue() const {
             return this->value;
         }
+        
+        void IntegerLiteralExpression::printToStream(std::ostream& stream) const {
+            stream << this->getValue();
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
index 1fc1b03f7..1b71ea306 100644
--- a/src/storage/expressions/IntegerLiteralExpression.h
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace expressions {
-        class IntegerLiteralExpression : BaseExpression {
+        class IntegerLiteralExpression : public BaseExpression {
         public:
             /*!
              * Creates an integer literal expression with the given value.
@@ -27,9 +27,8 @@ namespace storm {
             virtual bool isConstant() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
             
             /*!
              * Retrieves the value of the integer literal.
@@ -38,6 +37,10 @@ namespace storm {
              */
             int_fast64_t getValue() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The value of the integer literal.
             int_fast64_t value;
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index ea829557e..e2e230b64 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace expressions {
-        SimpleValuation::SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount) : identifierToIndexMap(), booleanValues(booleanVariableCount), integerValues(integerVariableCount), doubleValues(doubleVariableCount) {
+        SimpleValuation::SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount) : identifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>), booleanValues(booleanVariableCount), integerValues(integerVariableCount), doubleValues(doubleVariableCount) {
             // Intentionally left empty.
         }
         
@@ -15,15 +15,15 @@ namespace storm {
         }
         
         void SimpleValuation::setBooleanValue(std::string const& name, bool value) {
-            this->booleanValues[(*this->identifierToIndexMap)[name]] = value;
+            this->booleanValues[this->identifierToIndexMap->at(name)] = value;
         }
         
         void SimpleValuation::setIntegerValue(std::string const& name, int_fast64_t value) {
-            this->integerValues[(*this->identifierToIndexMap)[name]] = value;
+            this->integerValues[this->identifierToIndexMap->at(name)] = value;
         }
         
         void SimpleValuation::setDoubleValue(std::string const& name, double value) {
-            this->doubleValues[(*this->identifierToIndexMap)[name]] = value;
+            this->doubleValues[this->identifierToIndexMap->at(name)] = value;
         }
         
         bool SimpleValuation::getBooleanValue(std::string const& name) const {
@@ -40,5 +40,23 @@ namespace storm {
             auto const& nameIndexPair = this->identifierToIndexMap->find(name);
             return this->doubleValues[nameIndexPair->second];
         }
+        
+        std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation) {
+            stream << "valuation { bool[";
+            for (uint_fast64_t i = 0; i < valuation.booleanValues.size() - 1; ++i) {
+                stream << valuation.booleanValues[i] << ", ";
+            }
+            stream << valuation.booleanValues.back() << "] ints[";
+            for (uint_fast64_t i = 0; i < valuation.integerValues.size() - 1; ++i) {
+                stream << valuation.integerValues[i] << ", ";
+            }
+            stream << valuation.integerValues.back() << "] double[";
+            for (uint_fast64_t i = 0; i < valuation.doubleValues.size() - 1; ++i) {
+                stream << valuation.doubleValues[i] << ", ";
+            }
+            stream << valuation.doubleValues.back() << "] }";
+            
+            return stream;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index f4808face..8f0e9d161 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -4,6 +4,7 @@
 #include <memory>
 #include <vector>
 #include <unordered_map>
+#include <iostream>
 
 #include "src/storage/expressions/Valuation.h"
 
@@ -76,6 +77,8 @@ namespace storm {
             virtual int_fast64_t getIntegerValue(std::string const& name) const override;
             virtual double getDoubleValue(std::string const& name) const override;
             
+            friend std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation);
+
         private:
             // A mapping of identifiers to their local indices in the value containers.
             std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap;
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index 8c478d682..878d06036 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -3,15 +3,175 @@
 
 #include "src/storage/expressions/SubstitutionVisitor.h"
 
+#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/BinaryRelationExpression.h"
+#include "src/storage/expressions/BooleanConstantExpression.h"
+#include "src/storage/expressions/IntegerConstantExpression.h"
+#include "src/storage/expressions/DoubleConstantExpression.h"
+#include "src/storage/expressions/BooleanLiteralExpression.h"
+#include "src/storage/expressions/IntegerLiteralExpression.h"
+#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/VariableExpression.h"
+#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+
 namespace storm {
     namespace expressions  {
         template<template<typename... Arguments> class MapType>
-        Expression SubstitutionVisitor::substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap) {
-            return Expression();
+        SubstitutionVisitor<MapType>::SubstitutionVisitor(MapType<std::string, Expression> const& identifierToExpressionMap) : identifierToExpressionMap(identifierToExpressionMap) {
+            // Intentionally left empty.
+        }
+
+        template<template<typename... Arguments> class MapType>
+        Expression SubstitutionVisitor<MapType>::substitute(BaseExpression const* expression) {
+            expression->accept(this);
+            return Expression(this->expressionStack.top());
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getSecondOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> secondExpression = expressionStack.top();
+            expressionStack.pop();
+
+            // If the arguments did not change, we simply push the expression itself.
+            if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(BinaryNumericalFunctionExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getSecondOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> secondExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the arguments did not change, we simply push the expression itself.
+            if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(BinaryRelationExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getSecondOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> secondExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the arguments did not change, we simply push the expression itself.
+            if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getRelationType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
+            // If the boolean constant is in the key set of the substitution, we need to replace it.
+            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
+            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
+                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
+            // If the double constant is in the key set of the substitution, we need to replace it.
+            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
+            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
+                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
+            // If the integer constant is in the key set of the substitution, we need to replace it.
+            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
+            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
+                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(VariableExpression const* expression) {
+            // If the variable is in the key set of the substitution, we need to replace it.
+            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getVariableName());
+            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
+                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(UnaryBooleanFunctionExpression const* expression) {
+            expression->getOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the argument did not change, we simply push the expression itself.
+            if (operandExpression.get() == expression->getOperand().get()) {
+                expressionStack.push(expression->getSharedPointer());
+            } else {
+                expressionStack.push(std::shared_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(expression->getReturnType(), operandExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(UnaryNumericalFunctionExpression const* expression) {
+            expression->getOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the argument did not change, we simply push the expression itself.
+            if (operandExpression.get() == expression->getOperand().get()) {
+                expressionStack.push(expression->getSharedPointer());
+            } else {
+                expressionStack.push(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(expression->getReturnType(), operandExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(BooleanLiteralExpression const* expression) {
+            this->expressionStack.push(expression->getSharedPointer());
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(IntegerLiteralExpression const* expression) {
+            this->expressionStack.push(expression->getSharedPointer());
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(DoubleLiteralExpression const* expression) {
+            this->expressionStack.push(expression->getSharedPointer());
         }
         
-        // Explicitly instantiate substitute with map and unordered_map.
-        template Expression SubstitutionVisitor::substitute<std::map>(BaseExpression const* expression, std::map<std::string, Expression> const& identifierToExpressionMap);
-        template Expression SubstitutionVisitor::substitute<std::unordered_map>(BaseExpression const* expression, std::unordered_map<std::string, Expression> const& identifierToExpressionMap);
+        // Explicitly instantiate the class with map and unordered_map.
+        template class SubstitutionVisitor<std::map>;
+        template class SubstitutionVisitor<std::unordered_map>;
     }
 }
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index db2947e2e..4c3abc1e7 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -1,15 +1,52 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
 #define STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
 
+#include <stack>
+
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 
 namespace storm {
     namespace expressions {
+        template<template<typename... Arguments> class MapType>
         class SubstitutionVisitor : public ExpressionVisitor {
         public:
-            template<template<typename... Arguments> class MapType>
-            Expression substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap);
+            /*!
+             * Creates a new substitution visitor that uses the given map to replace identifiers.
+             *
+             * @param identifierToExpressionMap A mapping from identifiers to expressions.
+             */
+            SubstitutionVisitor(MapType<std::string, Expression> const& identifierToExpressionMap);
+            
+            /*!
+             * Substitutes the identifiers in the given expression according to the previously given map and returns the
+             * resulting expression.
+             *
+             * @param expression The expression in which to substitute the identifiers.
+             * @return The expression in which all identifiers in the key set of the previously given mapping are
+             * substituted with the mapped-to expressions.
+             */
+            Expression substitute(BaseExpression const* expression);
+            
+            virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BinaryRelationExpression const* expression) override;
+            virtual void visit(BooleanConstantExpression const* expression) override;
+            virtual void visit(DoubleConstantExpression const* expression) override;
+            virtual void visit(IntegerConstantExpression const* expression) override;
+            virtual void visit(VariableExpression const* expression) override;
+            virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BooleanLiteralExpression const* expression) override;
+            virtual void visit(IntegerLiteralExpression const* expression) override;
+            virtual void visit(DoubleLiteralExpression const* expression) override;
+            
+        private:
+            // A stack of expression used to pass the results to the higher levels.
+            std::stack<std::shared_ptr<BaseExpression const>> expressionStack;
+            
+            // A mapping of identifier names to expressions with which they shall be replaced.
+            MapType<std::string, Expression> const& identifierToExpressionMap;
         };
     }
 }
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
index d25460c3c..0b12b5bf6 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
@@ -1,42 +1,50 @@
 #include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BooleanLiteralExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
 
 namespace storm {
     namespace expressions {
-        UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType) : UnaryExpression(returnType, std::move(operand)), operatorType(operatorType) {
+        UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand, OperatorType operatorType) : UnaryExpression(returnType, operand), operatorType(operatorType) {
             // Intentionally left empty.
         }
         
-        OperatorType UnaryBooleanFunctionExpression::getOperatorType() const {
+        UnaryBooleanFunctionExpression::OperatorType UnaryBooleanFunctionExpression::getOperatorType() const {
             return this->operatorType;
         }
         
         bool UnaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
+            LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
+
             bool operandEvaluated = this->getOperand()->evaluateAsBool(valuation);
             switch (this->getOperatorType()) {
                 case OperatorType::Not: return !operandEvaluated; break;
             }
         }
         
-        std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::simplify() const {
-            std::unique_ptr<BaseExpression> operandSimplified = this->getOperand()->simplify();
+        std::shared_ptr<BaseExpression const> UnaryBooleanFunctionExpression::simplify() const {
+            std::shared_ptr<BaseExpression const> operandSimplified = this->getOperand()->simplify();
             switch (this->getOperatorType()) {
                 case OperatorType::Not: if (operandSimplified->isTrue()) {
-                    return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(false));
+                    return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(false));
                 } else {
-                    return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(true));
+                    return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(true));
                 }
             }
             
-            return UnaryBooleanFunctionExpression(this->getReturnType(), std::move(operandSimplified), this->getOperatorType());
+            if (operandSimplified.get() == this->getOperand().get()) {
+                return this->shared_from_this();
+            } else {
+                return std::shared_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(this->getReturnType(), operandSimplified, this->getOperatorType()));
+            }
         }
         
         void UnaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(*this));
+        void UnaryBooleanFunctionExpression::printToStream(std::ostream& stream) const {
+            stream << "!(" << *this->getOperand() << ")";
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h
index 8453f99e0..fefbded86 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h
@@ -6,10 +6,11 @@
 namespace storm {
     namespace expressions {
         class UnaryBooleanFunctionExpression : public UnaryExpression {
+        public:
             /*!
              * An enum type specifying the different functions applicable.
              */
-            enum class OperatorType {Not};
+            enum class OperatorType { Not };
             
             /*!
              * Creates a unary boolean function expression with the given return type, operand and operator.
@@ -18,7 +19,7 @@ namespace storm {
              * @param operand The operand of the expression.
              * @param operatorType The operator of the expression.
              */
-            UnaryBooleanFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType);
+            UnaryBooleanFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand, OperatorType operatorType);
 
             // Instantiate constructors and assignments with their default implementations.
             UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& other) = default;
@@ -29,9 +30,8 @@ namespace storm {
             
             // Override base class methods.
             virtual bool evaluateAsBool(Valuation const& valuation) const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
 
             /*!
              * Retrieves the operator associated with this expression.
@@ -40,6 +40,10 @@ namespace storm {
              */
             OperatorType getOperatorType() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The operator of this expression.
             OperatorType operatorType;
diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp
index e0573d813..1e2d9135e 100644
--- a/src/storage/expressions/UnaryExpression.cpp
+++ b/src/storage/expressions/UnaryExpression.cpp
@@ -2,21 +2,9 @@
 
 namespace storm {
     namespace expressions {
-        UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand) : BaseExpression(returnType), operand(std::move(operand)) {
+        UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand) : BaseExpression(returnType), operand(operand) {
             // Intentionally left empty.
         }
-        
-        UnaryExpression::UnaryExpression(UnaryExpression const& other) : BaseExpression(other), operand(other.getOperand()->clone()) {
-            // Intentionally left empty.
-        }
-        
-        UnaryExpression& UnaryExpression::operator=(UnaryExpression const& other) {
-            if (this != &other) {
-                BaseExpression::operator=(other);
-                this->operand = other.getOperand()->clone();
-            }
-            return *this;
-        }
 
         bool UnaryExpression::isConstant() const {
             return this->getOperand()->isConstant();
@@ -29,5 +17,9 @@ namespace storm {
         std::set<std::string> UnaryExpression::getConstants() const {
             return this->getOperand()->getVariables();
         }
+        
+        std::shared_ptr<BaseExpression const> const& UnaryExpression::getOperand() const {
+            return this->operand;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
index c0d4acf33..686e97c4e 100644
--- a/src/storage/expressions/UnaryExpression.h
+++ b/src/storage/expressions/UnaryExpression.h
@@ -13,13 +13,11 @@ namespace storm {
              * @param returnType The return type of the expression.
              * @param operand The operand of the unary expression.
              */
-            UnaryExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand);
+            UnaryExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand);
 
-            // Provide custom versions of copy construction and assignment.
+            // Instantiate constructors and assignments with their default implementations.
             UnaryExpression(UnaryExpression const& other);
             UnaryExpression& operator=(UnaryExpression const& other);
-            
-            // Create default variants of move construction/assignment and virtual destructor.
             UnaryExpression(UnaryExpression&&) = default;
             UnaryExpression& operator=(UnaryExpression&&) = default;
             virtual ~UnaryExpression() = default;
@@ -34,11 +32,11 @@ namespace storm {
              *
              * @return The operand of the unary expression.
              */
-            std::unique_ptr<BaseExpression> const& getOperand() const;
+            std::shared_ptr<BaseExpression const> const& getOperand() const;
             
         private:
             // The operand of the unary expression.
-            std::unique_ptr<BaseExpression> operand;
+            std::shared_ptr<BaseExpression const> operand;
         };
     }
 }
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
index fc8ef625b..31f9aeb1e 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
@@ -1,14 +1,22 @@
 #include <cmath>
 
 #include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
 
 namespace storm {
     namespace expressions {
-        UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType) : UnaryExpression(returnType, std::move(operand)), operatorType(operatorType) {
+        UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand, OperatorType operatorType) : UnaryExpression(returnType, operand), operatorType(operatorType) {
             // Intentionally left empty.
         }
         
+        UnaryNumericalFunctionExpression::OperatorType UnaryNumericalFunctionExpression::getOperatorType() const {
+            return this->operatorType;
+        }
+        
         int_fast64_t UnaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
+            LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
+
             int_fast64_t operandEvaluated = this->getOperand()->evaluateAsInt(valuation);
             switch (this->getOperatorType()) {
                 case OperatorType::Minus: return -operandEvaluated; break;
@@ -18,6 +26,8 @@ namespace storm {
         }
         
         double UnaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
+            LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
+
             double operandEvaluated = this->getOperand()->evaluateAsDouble(valuation);
             switch (this->getOperatorType()) {
                 case OperatorType::Minus: return -operandEvaluated; break;
@@ -26,16 +36,27 @@ namespace storm {
             }
         }
         
-        std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::simplify() const {
-            return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getReturnType(), this->getOperand()->simplify(), this->getOperatorType()));
+        std::shared_ptr<BaseExpression const> UnaryNumericalFunctionExpression::simplify() const {
+            std::shared_ptr<BaseExpression const> operandSimplified = this->getOperand()->simplify();
+            
+            if (operandSimplified.get() == this->getOperand().get()) {
+                return this->shared_from_this();
+            } else {
+                return std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getReturnType(), operandSimplified, this->getOperatorType()));
+            }
         }
         
         void UnaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(*this));
+        void UnaryNumericalFunctionExpression::printToStream(std::ostream& stream) const {
+            switch (this->getOperatorType()) {
+                case OperatorType::Minus: stream << "-("; break;
+                case OperatorType::Floor: stream << "floor("; break;
+                case OperatorType::Ceil: stream << "ceil("; break;
+            }
+            stream << *this->getOperand() << ")";
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h
index 7bbba69ca..2f50549ef 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h
@@ -6,6 +6,7 @@
 namespace storm {
     namespace expressions {
         class UnaryNumericalFunctionExpression : public UnaryExpression {
+        public:
             /*!
              * An enum type specifying the different functions applicable.
              */
@@ -18,7 +19,7 @@ namespace storm {
              * @param operand The operand of the expression.
              * @param operatorType The operator of the expression.
              */
-            UnaryNumericalFunctionExpression(ExpressionReturnType returnType, std::unique_ptr<BaseExpression>&& operand, OperatorType operatorType);
+            UnaryNumericalFunctionExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand, OperatorType operatorType);
             
             // Instantiate constructors and assignments with their default implementations.
             UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& other) = default;
@@ -30,10 +31,9 @@ namespace storm {
             // Override base class methods.
             virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
             virtual double evaluateAsDouble(Valuation const& valuation) const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
-            
+     
             /*!
              * Retrieves the operator associated with this expression.
              *
@@ -41,6 +41,10 @@ namespace storm {
              */
             OperatorType getOperatorType() const;
             
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The operator of this expression.
             OperatorType operatorType;
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
index 6cc96f799..b7a6ce6d2 100644
--- a/src/storage/expressions/VariableExpression.cpp
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -1,5 +1,6 @@
 #include "src/storage/expressions/VariableExpression.h"
 #include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
 
 namespace storm {
     namespace expressions {
@@ -11,19 +12,27 @@ namespace storm {
             return this->variableName;
         }
         
-        int_fast64_t VariableExpression::evaluateAsInt(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::Int), "Cannot evaluate expression as integer: return type is not an integer.");
-            return evaluation.getIntegerValue(this->getVariableName());
-        }
-        
         bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::Bool), "Cannot evaluate expression as integer: return type is not a boolean.");
+            LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Cannot evaluate expression as boolean: return type is not a boolean.");
+            
             return evaluation.getBooleanValue(this->getVariableName());
         }
+
+        int_fast64_t VariableExpression::evaluateAsInt(Valuation const& evaluation) const {
+            LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Cannot evaluate expression as integer: return type is not an integer.");
+            
+            return evaluation.getIntegerValue(this->getVariableName());
+        }
         
         double VariableExpression::evaluateAsDouble(Valuation const& evaluation) const {
-            LOG_ASSERT((this->getReturnType() == ExpressionReturnType::Double), "Cannot evaluate expression as integer: return type is not a double.");
-            return evaluation.getDoubleValue(this->getVariableName());
+            LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Cannot evaluate expression as double: return type is not a double.");
+            
+            switch (this->getReturnType()) {
+                case ExpressionReturnType::Int: return static_cast<double>(evaluation.getIntegerValue(this->getVariableName())); break;
+                case ExpressionReturnType::Double: evaluation.getDoubleValue(this->getVariableName()); break;
+                default: break;
+            }
+            LOG_THROW(false, storm::exceptions::InvalidTypeException, "Type of variable is required to be numeric.");
         }
         
         std::set<std::string> VariableExpression::getVariables() const {
@@ -34,16 +43,16 @@ namespace storm {
             return std::set<std::string>();
         }
         
-        std::unique_ptr<BaseExpression> VariableExpression::simplify() const {
-            return this->clone();
+        std::shared_ptr<BaseExpression const> VariableExpression::simplify() const {
+            return this->shared_from_this();
         }
         
         void VariableExpression::accept(ExpressionVisitor* visitor) const {
             visitor->visit(this);
         }
         
-        std::unique_ptr<BaseExpression> VariableExpression::clone() const {
-            return std::unique_ptr<BaseExpression>(new VariableExpression(*this));
+        void VariableExpression::printToStream(std::ostream& stream) const {
+            stream << this->getVariableName();
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index 5aa89e4ce..7e4732eda 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -6,6 +6,13 @@
 namespace storm {
     namespace expressions {
         class VariableExpression : public BaseExpression {
+        public:
+            /*!
+             * Creates a variable expression with the given return type and variable name.
+             *
+             * @param returnType The return type of the variable expression.
+             * @param variableName The name of the variable associated with this expression.
+             */
             VariableExpression(ExpressionReturnType returnType, std::string const& variableName);
             
             // Instantiate constructors and assignments with their default implementations.
@@ -21,9 +28,8 @@ namespace storm {
             virtual double evaluateAsDouble(Valuation const& valuation) const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
-            virtual std::unique_ptr<BaseExpression> simplify() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::unique_ptr<BaseExpression> clone() const override;
 
             /*!
              * Retrieves the name of the variable associated with this expression.
@@ -32,6 +38,10 @@ namespace storm {
              */
             std::string const& getVariableName() const;
 
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+
         private:
             // The variable name associated with this expression.
             std::string variableName;
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 9d9307bea..a7f789769 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -1,9 +1,358 @@
-#include "gtest/gtest.h"
-
 #include <map>
 
+#include "gtest/gtest.h"
+#include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/SimpleValuation.h"
+#include "src/exceptions/InvalidTypeException.h"
+
+TEST(Expression, FactoryMethodTest) {
+    EXPECT_NO_THROW(storm::expressions::Expression::createBooleanLiteral(true));
+    EXPECT_NO_THROW(storm::expressions::Expression::createTrue());
+    EXPECT_NO_THROW(storm::expressions::Expression::createFalse());
+    EXPECT_NO_THROW(storm::expressions::Expression::createIntegerLiteral(3));
+    EXPECT_NO_THROW(storm::expressions::Expression::createDoubleLiteral(3.14));
+    EXPECT_NO_THROW(storm::expressions::Expression::createBooleanVariable("x"));
+    EXPECT_NO_THROW(storm::expressions::Expression::createIntegerVariable("y"));
+    EXPECT_NO_THROW(storm::expressions::Expression::createDoubleVariable("z"));
+    EXPECT_NO_THROW(storm::expressions::Expression::createBooleanConstant("a"));
+    EXPECT_NO_THROW(storm::expressions::Expression::createIntegerConstant("b"));
+    EXPECT_NO_THROW(storm::expressions::Expression::createDoubleConstant("c"));
+}
+
+TEST(Expression, AccessorTest) {
+    storm::expressions::Expression trueExpression;
+    storm::expressions::Expression falseExpression;
+    storm::expressions::Expression threeExpression;
+    storm::expressions::Expression piExpression;
+    storm::expressions::Expression boolVarExpression;
+    storm::expressions::Expression intVarExpression;
+    storm::expressions::Expression doubleVarExpression;
+    storm::expressions::Expression boolConstExpression;
+    storm::expressions::Expression intConstExpression;
+    storm::expressions::Expression doubleConstExpression;
+    
+    ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
+    ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
+    ASSERT_NO_THROW(threeExpression = storm::expressions::Expression::createIntegerLiteral(3));
+    ASSERT_NO_THROW(piExpression = storm::expressions::Expression::createDoubleLiteral(3.14));
+    ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
+    ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
+    ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
+    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
+    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
+    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
+    
+    EXPECT_TRUE(trueExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    EXPECT_TRUE(trueExpression.isConstant());
+    EXPECT_TRUE(trueExpression.isTrue());
+    EXPECT_FALSE(trueExpression.isFalse());
+    EXPECT_TRUE(trueExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(trueExpression.getConstants() == std::set<std::string>());
+    
+    EXPECT_TRUE(falseExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    EXPECT_TRUE(falseExpression.isConstant());
+    EXPECT_FALSE(falseExpression.isTrue());
+    EXPECT_TRUE(falseExpression.isFalse());
+    EXPECT_TRUE(falseExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(falseExpression.getConstants() == std::set<std::string>());
+
+    EXPECT_TRUE(threeExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    EXPECT_TRUE(threeExpression.isConstant());
+    EXPECT_FALSE(threeExpression.isTrue());
+    EXPECT_FALSE(threeExpression.isFalse());
+    EXPECT_TRUE(threeExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(threeExpression.getConstants() == std::set<std::string>());
+    
+    EXPECT_TRUE(piExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    EXPECT_TRUE(piExpression.isConstant());
+    EXPECT_FALSE(piExpression.isTrue());
+    EXPECT_FALSE(piExpression.isFalse());
+    EXPECT_TRUE(piExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(piExpression.getConstants() == std::set<std::string>());
+    
+    EXPECT_TRUE(boolVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    EXPECT_FALSE(boolVarExpression.isConstant());
+    EXPECT_FALSE(boolVarExpression.isTrue());
+    EXPECT_FALSE(boolVarExpression.isFalse());
+    EXPECT_TRUE(boolVarExpression.getVariables() == std::set<std::string>({"x"}));
+    EXPECT_TRUE(boolVarExpression.getConstants() == std::set<std::string>());
+
+    EXPECT_TRUE(intVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    EXPECT_FALSE(intVarExpression.isConstant());
+    EXPECT_FALSE(intVarExpression.isTrue());
+    EXPECT_FALSE(intVarExpression.isFalse());
+    EXPECT_TRUE(intVarExpression.getVariables() == std::set<std::string>({"y"}));
+    EXPECT_TRUE(intVarExpression.getConstants() == std::set<std::string>());
+
+    EXPECT_TRUE(doubleVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    EXPECT_FALSE(doubleVarExpression.isConstant());
+    EXPECT_FALSE(doubleVarExpression.isTrue());
+    EXPECT_FALSE(doubleVarExpression.isFalse());
+    EXPECT_TRUE(doubleVarExpression.getVariables() == std::set<std::string>({"z"}));
+    EXPECT_TRUE(doubleVarExpression.getConstants() == std::set<std::string>());
+
+    EXPECT_TRUE(boolConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    EXPECT_FALSE(boolConstExpression.isConstant());
+    EXPECT_FALSE(boolConstExpression.isTrue());
+    EXPECT_FALSE(boolConstExpression.isFalse());
+    EXPECT_TRUE(boolConstExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(boolConstExpression.getConstants() == std::set<std::string>({"a"}));
+    
+    EXPECT_TRUE(intConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    EXPECT_FALSE(intConstExpression.isConstant());
+    EXPECT_FALSE(intConstExpression.isTrue());
+    EXPECT_FALSE(intConstExpression.isFalse());
+    EXPECT_TRUE(intConstExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(intConstExpression.getConstants() == std::set<std::string>({"b"}));
+
+    EXPECT_TRUE(doubleConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    EXPECT_FALSE(doubleConstExpression.isConstant());
+    EXPECT_FALSE(doubleConstExpression.isTrue());
+    EXPECT_FALSE(doubleConstExpression.isFalse());
+    EXPECT_TRUE(doubleConstExpression.getVariables() == std::set<std::string>());
+    EXPECT_TRUE(doubleConstExpression.getConstants() == std::set<std::string>({"c"}));
+}
+
+TEST(Expression, OperatorTest) {
+    storm::expressions::Expression trueExpression;
+    storm::expressions::Expression falseExpression;
+    storm::expressions::Expression threeExpression;
+    storm::expressions::Expression piExpression;
+    storm::expressions::Expression boolVarExpression;
+    storm::expressions::Expression intVarExpression;
+    storm::expressions::Expression doubleVarExpression;
+    storm::expressions::Expression boolConstExpression;
+    storm::expressions::Expression intConstExpression;
+    storm::expressions::Expression doubleConstExpression;
+    
+    ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
+    ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
+    ASSERT_NO_THROW(threeExpression = storm::expressions::Expression::createIntegerLiteral(3));
+    ASSERT_NO_THROW(piExpression = storm::expressions::Expression::createDoubleLiteral(3.14));
+    ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
+    ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
+    ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
+    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
+    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
+    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
+    
+    storm::expressions::Expression tempExpression;
+
+    ASSERT_THROW(tempExpression = trueExpression + piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression + threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = threeExpression + piExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression + doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    
+    ASSERT_THROW(tempExpression = trueExpression - piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression - threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = threeExpression - piExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression - doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    
+    ASSERT_THROW(tempExpression = -trueExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = -threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = -piExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    ASSERT_NO_THROW(tempExpression = -doubleVarExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+
+    ASSERT_THROW(tempExpression = trueExpression * piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression * threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = threeExpression * piExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    ASSERT_NO_THROW(tempExpression = intVarExpression * intConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+
+    ASSERT_THROW(tempExpression = trueExpression / piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression / threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = threeExpression / piExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression / intConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+
+    ASSERT_THROW(tempExpression = trueExpression && piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = trueExpression && falseExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression && boolConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+
+    ASSERT_THROW(tempExpression = trueExpression || piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = trueExpression || falseExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression || boolConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+
+    ASSERT_THROW(tempExpression = !threeExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = !trueExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = !boolVarExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+
+    ASSERT_THROW(tempExpression = trueExpression == piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression == threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = intVarExpression == doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+
+    ASSERT_THROW(tempExpression = trueExpression != piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression != threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = intVarExpression != doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+
+    ASSERT_THROW(tempExpression = trueExpression > piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression > threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = intVarExpression > doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
+    ASSERT_THROW(tempExpression = trueExpression >= piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression >= threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = intVarExpression >= doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
+    ASSERT_THROW(tempExpression = trueExpression < piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression < threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = intVarExpression < doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
+    ASSERT_THROW(tempExpression = trueExpression <= piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression <= threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = intVarExpression <= doubleConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
+    ASSERT_THROW(tempExpression = storm::expressions::Expression::minimum(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::minimum(threeExpression, threeExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::minimum(intVarExpression, doubleConstExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+
+    ASSERT_THROW(tempExpression = storm::expressions::Expression::maximum(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::maximum(threeExpression, threeExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::maximum(intVarExpression, doubleConstExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    
+    ASSERT_THROW(tempExpression = trueExpression.floor(), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression.floor());
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = doubleConstExpression.floor());
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+
+    ASSERT_THROW(tempExpression = trueExpression.ceil(), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression.ceil());
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = doubleConstExpression.ceil());
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+}
+
+TEST(Expression, SubstitutionTest) {
+    storm::expressions::Expression trueExpression;
+    storm::expressions::Expression falseExpression;
+    storm::expressions::Expression threeExpression;
+    storm::expressions::Expression piExpression;
+    storm::expressions::Expression boolVarExpression;
+    storm::expressions::Expression intVarExpression;
+    storm::expressions::Expression doubleVarExpression;
+    storm::expressions::Expression boolConstExpression;
+    storm::expressions::Expression intConstExpression;
+    storm::expressions::Expression doubleConstExpression;
+    
+    ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
+    ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
+    ASSERT_NO_THROW(threeExpression = storm::expressions::Expression::createIntegerLiteral(3));
+    ASSERT_NO_THROW(piExpression = storm::expressions::Expression::createDoubleLiteral(3.14));
+    ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
+    ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
+    ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
+    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
+    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
+    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
+    
+    storm::expressions::Expression tempExpression;
+    ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolConstExpression);
+
+    std::map<std::string, storm::expressions::Expression> substution = { std::make_pair("y", doubleConstExpression), std::make_pair("x", storm::expressions::Expression::createTrue()), std::make_pair("a", storm::expressions::Expression::createTrue()) };
+    storm::expressions::Expression substitutedExpression;
+    ASSERT_NO_THROW(substitutedExpression = tempExpression.substitute<std::map>(substution));
+    EXPECT_TRUE(substitutedExpression.simplify().isTrue());
+}
+
+TEST(Expression, SimplificationTest) {
+    storm::expressions::Expression trueExpression;
+    storm::expressions::Expression falseExpression;
+    storm::expressions::Expression threeExpression;
+    storm::expressions::Expression intVarExpression;
+    
+    ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
+    ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
+    ASSERT_NO_THROW(threeExpression = storm::expressions::Expression::createIntegerLiteral(3));
+    ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
+    
+    storm::expressions::Expression tempExpression;
+    storm::expressions::Expression simplifiedExpression;
+
+    ASSERT_NO_THROW(tempExpression = trueExpression || intVarExpression > threeExpression);
+    ASSERT_NO_THROW(simplifiedExpression = tempExpression.simplify());
+    EXPECT_TRUE(simplifiedExpression.isTrue());
+
+    ASSERT_NO_THROW(tempExpression = falseExpression && intVarExpression > threeExpression);
+    ASSERT_NO_THROW(simplifiedExpression = tempExpression.simplify());
+    EXPECT_TRUE(simplifiedExpression.isFalse());
+}
 
-TEST(Expression, SimpleValuationTest) {
-    ASSERT_NO_THROW(storm::expressions::SimpleValuation evaluation(1, 1, 1));
+TEST(Expression, SimpleEvaluationTest) {
+    storm::expressions::Expression trueExpression;
+    storm::expressions::Expression falseExpression;
+    storm::expressions::Expression threeExpression;
+    storm::expressions::Expression piExpression;
+    storm::expressions::Expression boolVarExpression;
+    storm::expressions::Expression intVarExpression;
+    storm::expressions::Expression doubleVarExpression;
+    storm::expressions::Expression boolConstExpression;
+    storm::expressions::Expression intConstExpression;
+    storm::expressions::Expression doubleConstExpression;
+    
+    ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
+    ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
+    ASSERT_NO_THROW(threeExpression = storm::expressions::Expression::createIntegerLiteral(3));
+    ASSERT_NO_THROW(piExpression = storm::expressions::Expression::createDoubleLiteral(3.14));
+    ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
+    ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
+    ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
+    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
+    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
+    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
+    
+    storm::expressions::Expression tempExpression;
+    
+    ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolConstExpression);
+    
+    ASSERT_NO_THROW(storm::expressions::SimpleValuation valuation(2, 2, 2));
+    storm::expressions::SimpleValuation valuation(2, 2, 2);
+    ASSERT_NO_THROW(valuation.setIdentifierIndex("x", 0));
+    ASSERT_NO_THROW(valuation.setIdentifierIndex("a", 1));
+    ASSERT_NO_THROW(valuation.setIdentifierIndex("y", 0));
+    ASSERT_NO_THROW(valuation.setIdentifierIndex("b", 1));
+    ASSERT_NO_THROW(valuation.setIdentifierIndex("z", 0));
+    ASSERT_NO_THROW(valuation.setIdentifierIndex("c", 1));
+    
+    ASSERT_THROW(tempExpression.evaluateAsDouble(valuation), storm::exceptions::InvalidTypeException);
+    ASSERT_THROW(tempExpression.evaluateAsInt(valuation), storm::exceptions::InvalidTypeException);
+    EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
+    ASSERT_NO_THROW(valuation.setBooleanValue("a", true));
+    EXPECT_TRUE(tempExpression.evaluateAsBool(valuation));
+    ASSERT_NO_THROW(valuation.setIntegerValue("y", 3));
+    EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
 }
\ No newline at end of file

From 6e1241211bc9036d6aff5dd3330fde88f0850487 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 6 Apr 2014 20:23:30 +0200
Subject: [PATCH 058/147] Started moving IR and adjusting it to the new
 expression classes.

Former-commit-id: 24a182701fd4c3c4b58263e6a56928bf466097ff
---
 CMakeLists.txt                                |   7 +-
 src/ir/Assignment.cpp                         |  63 ----
 src/ir/Assignment.h                           |  98 ------
 src/ir/BooleanVariable.cpp                    |  49 ---
 src/ir/BooleanVariable.h                      |  70 ----
 src/ir/IR.h                                   |  25 --
 src/ir/IntegerVariable.cpp                    |  72 ----
 src/ir/IntegerVariable.h                      |  98 ------
 src/ir/Program.h                              | 318 ------------------
 src/ir/StateReward.cpp                        |  60 ----
 src/ir/TransitionReward.cpp                   |  65 ----
 src/ir/Update.cpp                             | 130 -------
 src/ir/Variable.cpp                           |  74 ----
 src/ir/Variable.h                             | 124 -------
 src/ir/expressions/BaseExpression.cpp         |  85 -----
 src/ir/expressions/BaseExpression.h           | 172 ----------
 .../BinaryBooleanFunctionExpression.cpp       |  67 ----
 .../BinaryBooleanFunctionExpression.h         |  69 ----
 src/ir/expressions/BinaryExpression.cpp       |  52 ---
 src/ir/expressions/BinaryExpression.h         |  66 ----
 .../BinaryNumericalFunctionExpression.cpp     |  96 ------
 .../BinaryNumericalFunctionExpression.h       |  72 ----
 .../expressions/BinaryRelationExpression.cpp  |  75 -----
 src/ir/expressions/BinaryRelationExpression.h |  69 ----
 .../expressions/BooleanConstantExpression.cpp |  45 ---
 .../expressions/BooleanConstantExpression.h   |  49 ---
 .../expressions/BooleanLiteralExpression.cpp  |  49 ---
 src/ir/expressions/BooleanLiteralExpression.h |  55 ---
 src/ir/expressions/ConstantExpression.h       | 132 --------
 .../expressions/DoubleConstantExpression.cpp  |  45 ---
 src/ir/expressions/DoubleConstantExpression.h |  49 ---
 .../expressions/DoubleLiteralExpression.cpp   |  49 ---
 src/ir/expressions/DoubleLiteralExpression.h  |  55 ---
 src/ir/expressions/ExpressionVisitor.h        |  49 ---
 src/ir/expressions/Expressions.h              |  26 --
 .../expressions/IntegerConstantExpression.cpp |  48 ---
 .../expressions/IntegerConstantExpression.h   |  51 ---
 .../expressions/IntegerLiteralExpression.cpp  |  53 ---
 src/ir/expressions/IntegerLiteralExpression.h |  57 ----
 .../UnaryBooleanFunctionExpression.cpp        |  62 ----
 .../UnaryBooleanFunctionExpression.h          |  68 ----
 src/ir/expressions/UnaryExpression.cpp        |  39 ---
 src/ir/expressions/UnaryExpression.h          |  55 ---
 .../UnaryNumericalFunctionExpression.cpp      |  86 -----
 .../UnaryNumericalFunctionExpression.h        |  70 ----
 src/ir/expressions/VariableExpression.cpp     | 120 -------
 src/ir/expressions/VariableExpression.h       |  98 ------
 src/storage/dd/CuddDd.cpp                     | 146 ++++----
 src/storage/dd/CuddDd.h                       |  60 ++--
 src/storage/dd/CuddDdManager.cpp              |  60 ++--
 src/storage/dd/CuddDdManager.h                |  28 +-
 src/storage/dd/DdMetaVariable.cpp             |   2 +-
 src/storage/dd/DdType.h                       |   2 +-
 src/storage/expressions/Expression.cpp        |   8 +
 src/storage/expressions/Expression.h          |  10 +
 .../IdentifierSubstitutionVisitor.cpp         | 177 ++++++++++
 .../IdentifierSubstitutionVisitor.h           |  54 +++
 src/storage/prism/Assignment.cpp              |  30 ++
 src/storage/prism/Assignment.h                |  61 ++++
 src/storage/prism/BooleanVariable.cpp         |  23 ++
 src/storage/prism/BooleanVariable.h           |  50 +++
 src/{ir => storage/prism}/Command.cpp         |   0
 src/{ir => storage/prism}/Command.h           |   0
 src/storage/prism/IntegerVariable.cpp         |  30 ++
 src/storage/prism/IntegerVariable.h           |  74 ++++
 src/{ir => storage/prism}/Module.cpp          |   0
 src/{ir => storage/prism}/Module.h            |   0
 src/{ir => storage/prism}/Program.cpp         |   0
 src/storage/prism/Program.h                   | 227 +++++++++++++
 src/{ir => storage/prism}/RewardModel.cpp     |   0
 src/{ir => storage/prism}/RewardModel.h       |   0
 src/storage/prism/StateReward.cpp             |  38 +++
 src/{ir => storage/prism}/StateReward.h       |  16 +-
 src/storage/prism/TransitionReward.cpp        |  42 +++
 src/{ir => storage/prism}/TransitionReward.h  |  16 +-
 src/storage/prism/Update.cpp                  |  94 ++++++
 src/{ir => storage/prism}/Update.h            |  94 ++----
 src/storage/prism/Variable.cpp                |  23 ++
 src/storage/prism/Variable.h                  |  64 ++++
 test/functional/storage/CuddDdTest.cpp        |  68 ++--
 80 files changed, 1233 insertions(+), 3750 deletions(-)
 delete mode 100644 src/ir/Assignment.cpp
 delete mode 100644 src/ir/Assignment.h
 delete mode 100644 src/ir/BooleanVariable.cpp
 delete mode 100644 src/ir/BooleanVariable.h
 delete mode 100644 src/ir/IR.h
 delete mode 100644 src/ir/IntegerVariable.cpp
 delete mode 100644 src/ir/IntegerVariable.h
 delete mode 100644 src/ir/Program.h
 delete mode 100644 src/ir/StateReward.cpp
 delete mode 100644 src/ir/TransitionReward.cpp
 delete mode 100644 src/ir/Update.cpp
 delete mode 100644 src/ir/Variable.cpp
 delete mode 100644 src/ir/Variable.h
 delete mode 100644 src/ir/expressions/BaseExpression.cpp
 delete mode 100644 src/ir/expressions/BaseExpression.h
 delete mode 100644 src/ir/expressions/BinaryBooleanFunctionExpression.cpp
 delete mode 100644 src/ir/expressions/BinaryBooleanFunctionExpression.h
 delete mode 100644 src/ir/expressions/BinaryExpression.cpp
 delete mode 100644 src/ir/expressions/BinaryExpression.h
 delete mode 100644 src/ir/expressions/BinaryNumericalFunctionExpression.cpp
 delete mode 100644 src/ir/expressions/BinaryNumericalFunctionExpression.h
 delete mode 100644 src/ir/expressions/BinaryRelationExpression.cpp
 delete mode 100644 src/ir/expressions/BinaryRelationExpression.h
 delete mode 100644 src/ir/expressions/BooleanConstantExpression.cpp
 delete mode 100644 src/ir/expressions/BooleanConstantExpression.h
 delete mode 100644 src/ir/expressions/BooleanLiteralExpression.cpp
 delete mode 100644 src/ir/expressions/BooleanLiteralExpression.h
 delete mode 100644 src/ir/expressions/ConstantExpression.h
 delete mode 100644 src/ir/expressions/DoubleConstantExpression.cpp
 delete mode 100644 src/ir/expressions/DoubleConstantExpression.h
 delete mode 100644 src/ir/expressions/DoubleLiteralExpression.cpp
 delete mode 100644 src/ir/expressions/DoubleLiteralExpression.h
 delete mode 100644 src/ir/expressions/ExpressionVisitor.h
 delete mode 100644 src/ir/expressions/Expressions.h
 delete mode 100644 src/ir/expressions/IntegerConstantExpression.cpp
 delete mode 100644 src/ir/expressions/IntegerConstantExpression.h
 delete mode 100644 src/ir/expressions/IntegerLiteralExpression.cpp
 delete mode 100644 src/ir/expressions/IntegerLiteralExpression.h
 delete mode 100644 src/ir/expressions/UnaryBooleanFunctionExpression.cpp
 delete mode 100644 src/ir/expressions/UnaryBooleanFunctionExpression.h
 delete mode 100644 src/ir/expressions/UnaryExpression.cpp
 delete mode 100644 src/ir/expressions/UnaryExpression.h
 delete mode 100644 src/ir/expressions/UnaryNumericalFunctionExpression.cpp
 delete mode 100644 src/ir/expressions/UnaryNumericalFunctionExpression.h
 delete mode 100644 src/ir/expressions/VariableExpression.cpp
 delete mode 100644 src/ir/expressions/VariableExpression.h
 create mode 100644 src/storage/expressions/IdentifierSubstitutionVisitor.cpp
 create mode 100644 src/storage/expressions/IdentifierSubstitutionVisitor.h
 create mode 100644 src/storage/prism/Assignment.cpp
 create mode 100644 src/storage/prism/Assignment.h
 create mode 100644 src/storage/prism/BooleanVariable.cpp
 create mode 100644 src/storage/prism/BooleanVariable.h
 rename src/{ir => storage/prism}/Command.cpp (100%)
 rename src/{ir => storage/prism}/Command.h (100%)
 create mode 100644 src/storage/prism/IntegerVariable.cpp
 create mode 100644 src/storage/prism/IntegerVariable.h
 rename src/{ir => storage/prism}/Module.cpp (100%)
 rename src/{ir => storage/prism}/Module.h (100%)
 rename src/{ir => storage/prism}/Program.cpp (100%)
 create mode 100644 src/storage/prism/Program.h
 rename src/{ir => storage/prism}/RewardModel.cpp (100%)
 rename src/{ir => storage/prism}/RewardModel.h (100%)
 create mode 100644 src/storage/prism/StateReward.cpp
 rename src/{ir => storage/prism}/StateReward.h (78%)
 create mode 100644 src/storage/prism/TransitionReward.cpp
 rename src/{ir => storage/prism}/TransitionReward.h (79%)
 create mode 100644 src/storage/prism/Update.cpp
 rename src/{ir => storage/prism}/Update.h (54%)
 create mode 100644 src/storage/prism/Variable.cpp
 create mode 100644 src/storage/prism/Variable.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7913af7d7..77b5c64a0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -252,10 +252,8 @@ file(GLOB_RECURSE STORM_SOLVER_FILES ${PROJECT_SOURCE_DIR}/src/solver/*.h ${PROJ
 file(GLOB STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp)
 file(GLOB_RECURSE STORM_STORAGE_DD_FILES ${PROJECT_SOURCE_DIR}/src/storage/dd/*.h ${PROJECT_SOURCE_DIR}/src/storage/dd/*.cpp)
 file(GLOB_RECURSE STORM_STORAGE_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/storage/expressions/*.h ${PROJECT_SOURCE_DIR}/src/storage/expressions/*.cpp)
+file(GLOB_RECURSE STORM_STORAGE_PRISM_FILES ${PROJECT_SOURCE_DIR}/src/storage/prism/*.h ${PROJECT_SOURCE_DIR}/src/storage/prism/*.cpp)
 file(GLOB_RECURSE STORM_UTILITY_FILES ${PROJECT_SOURCE_DIR}/src/utility/*.h ${PROJECT_SOURCE_DIR}/src/utility/*.cpp)
-file(GLOB STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp)
-file(GLOB_RECURSE STORM_IR_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.h ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.cpp)
-
 # Test Sources
 # Note that the tests also need the source files, except for the main file
 file(GLOB_RECURSE STORM_FUNCTIONAL_TEST_FILES ${STORM_CPP_TESTS_BASE_PATH}/functional/*.h ${STORM_CPP_TESTS_BASE_PATH}/functional/*.cpp)
@@ -274,8 +272,6 @@ source_group(formula\\csl FILES ${STORM_FORMULA_CSL_FILES})
 source_group(formula\\ltl FILES ${STORM_FORMULA_LTL_FILES})
 source_group(formula\\prctl FILES ${STORM_FORMULA_PRCTL_FILES})
 source_group(generated FILES ${STORM_BUILD_HEADERS})
-source_group(ir FILES ${STORM_IR_FILES})
-source_group(ir\\expressions FILES ${STORM_IR_EXPRESSIONS_FILES})
 source_group(modelchecker FILES ${STORM_MODELCHECKER_FILES})
 source_group(counterexamples FILES ${STORM_COUNTEREXAMPLES_FILES})
 source_group(models FILES ${STORM_MODELS_FILES})
@@ -286,6 +282,7 @@ source_group(solver FILES ${STORM_SOLVER_FILES})
 source_group(storage FILES ${STORM_STORAGE_FILES})
 source_group(storage\\dd FILES ${STORM_STORAGE_DD_FILES})
 source_group(storage\\expressions FILES ${STORM_STORAGE_EXPRESSIONS_FILES})
+source_group(storage\\prism FILES ${STORM_STORAGE_PRISM_FILES})
 source_group(utility FILES ${STORM_UTILITY_FILES})
 source_group(functional-test FILES ${STORM_FUNCTIONAL_TEST_FILES})
 source_group(performance-test FILES ${STORM_PERFORMANCE_TEST_FILES})
diff --git a/src/ir/Assignment.cpp b/src/ir/Assignment.cpp
deleted file mode 100644
index a50847afb..000000000
--- a/src/ir/Assignment.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Assignment.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "Assignment.h"
-#include "src/parser/prismparser/VariableState.h"
-
-namespace storm {
-    namespace ir {
-        
-        Assignment::Assignment() : variableName(), expression() {
-            // Nothing to do here.
-        }
-        
-        Assignment::Assignment(std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& expression)
-        : variableName(variableName), expression(std::move(expression)) {
-            // Nothing to do here.
-        }
-        
-        Assignment::Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
-        : variableName(oldAssignment.variableName), expression(oldAssignment.expression->clone(renaming, variableState)) {
-            auto renamingPair = renaming.find(oldAssignment.variableName);
-            if (renamingPair != renaming.end()) {
-                this->variableName = renamingPair->second;
-            }
-        }
-        
-        Assignment::Assignment(Assignment const& otherAssignment) : variableName(otherAssignment.variableName), expression() {
-            if (otherAssignment.expression != nullptr) {
-                expression = otherAssignment.expression->clone();
-            }
-        }
-        
-        Assignment& Assignment::operator=(Assignment const& otherAssignment) {
-            if (this != &otherAssignment) {
-                this->variableName = otherAssignment.variableName;
-                this->expression = otherAssignment.expression->clone();
-            }
-            
-            return *this;
-        }
-        
-        std::string const& Assignment::getVariableName() const {
-            return variableName;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& Assignment::getExpression() const {
-            return expression;
-        }
-        
-        std::string Assignment::toString() const {
-            std::stringstream result;
-            result << "(" << variableName << "' = " << expression->toString() << ")";
-            return result.str();
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/Assignment.h b/src/ir/Assignment.h
deleted file mode 100644
index 12d96a413..000000000
--- a/src/ir/Assignment.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Assignment.h
- *
- *  Created on: 06.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_ASSIGNMENT_H_
-#define STORM_IR_ASSIGNMENT_H_
-
-#include <memory>
-
-#include "expressions/BaseExpression.h"
-
-namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing the assignment of an expression to a variable.
-         */
-        class Assignment {
-        public:
-            /*!
-             * Default constructor. Creates an empty assignment.
-             */
-            Assignment();
-            
-            /*!
-             * Constructs an assignment using the given variable name and expression.
-             *
-             * @param variableName The variable that this assignment targets.
-             * @param expression The expression to assign to the variable.
-             */
-            Assignment(std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& expression);
-            
-            /*!
-             * Creates a copy of the given assignment and performs the provided renaming.
-             *
-             * @param oldAssignment The assignment to copy.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param variableState An object knowing about the variables in the system.
-             */
-            Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
-            
-            /*!
-             * Performs a deep-copy of the given assignment.
-             *
-             * @param otherAssignment The assignment to copy.
-             */
-            Assignment(Assignment const& otherAssignment);
-            
-            /*!
-             * Performs a deep-copy of the given assignment and assigns it to the current one.
-             *
-             * @param otherAssignment The assignment to assign.
-             */
-            Assignment& operator=(Assignment const& otherAssignment);
-            
-            /*!
-             * Retrieves the name of the variable that this assignment targets.
-             *
-             * @return The name of the variable that this assignment targets.
-             */
-            std::string const& getVariableName() const;
-            
-            /*!
-             * Retrieves the expression that is assigned to the variable.
-             *
-             * @return The expression that is assigned to the variable.
-             */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getExpression() const;
-            
-            /*!
-             * Retrieves a string representation of this assignment.
-             * @returns a string representation of this assignment.
-             */
-            std::string toString() const;
-            
-        private:
-            // The name of the variable that this assignment targets.
-            std::string variableName;
-            
-            // The expression that is assigned to the variable.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> expression;
-        };
-        
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_ASSIGNMENT_H_ */
diff --git a/src/ir/BooleanVariable.cpp b/src/ir/BooleanVariable.cpp
deleted file mode 100644
index 843655be9..000000000
--- a/src/ir/BooleanVariable.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * BooleanVariable.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "BooleanVariable.h"
-#include "src/parser/prismparser/VariableState.h"
-
-namespace storm {
-    namespace ir {
-        
-        BooleanVariable::BooleanVariable() : Variable() {
-            // Nothing to do here.
-        }
-        
-        BooleanVariable::BooleanVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue)
-		: Variable(localIndex, globalIndex, variableName, std::move(initialValue)) {
-            // Nothing to do here.
-        }
-        
-        BooleanVariable::BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
-        : Variable(oldVariable, newName, newGlobalIndex, renaming, variableState) {
-            // Nothing to do here.
-        }
-        
-        BooleanVariable& BooleanVariable::operator=(BooleanVariable const& otherVariable) {
-            if (this != &otherVariable) {
-                Variable::operator=(otherVariable);
-            }
-            
-            return *this;
-        }
-        
-        std::string BooleanVariable::toString() const {
-            std::stringstream result;
-            result << this->getName() << ": bool";
-            if (this->getInitialValue() != nullptr) {
-                result << " init " << this->getInitialValue()->toString();
-            }
-            result << ";";
-            return result.str();
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/BooleanVariable.h b/src/ir/BooleanVariable.h
deleted file mode 100644
index b968d7890..000000000
--- a/src/ir/BooleanVariable.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * BooleanVariable.h
- *
- *  Created on: 08.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_BOOLEANVARIABLE_H_
-#define STORM_IR_BOOLEANVARIABLE_H_
-
-#include <memory>
-#include <map>
-
-#include "src/ir/Variable.h"
-
-namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing a boolean variable.
-         */
-        class BooleanVariable : public Variable {
-        public:
-            /*!
-             * Default constructor. Creates a boolean variable without a name.
-             */
-            BooleanVariable();
-            
-            /*!
-             * Creates a boolean variable with the given name and the given initial value.
-             *
-             * @param localIndex A module-local unique index for the variable.
-             * @param globalIndex A globally unique index for the variable.
-             * @param variableName The name of the variable.
-             * @param initialValue The expression that defines the initial value of the variable.
-             */
-            BooleanVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue = nullptr);
-            
-            /*!
-             * Creates a copy of the given boolean variable and performs the provided renaming.
-             *
-             * @param oldVariable The variable to copy.
-             * @param newName New name of this variable.
-             * @param newGlobalIndex The new global index of the variable.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param variableState An object knowing about the variables in the system.
-             */
-            BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
-            
-            BooleanVariable& operator=(BooleanVariable const& otherVariable);
-            
-            /*!
-             * Retrieves a string representation of this variable.
-             * @returns a string representation of this variable.
-             */
-            std::string toString() const;
-        };
-        
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_BOOLEANVARIABLE_H_ */
diff --git a/src/ir/IR.h b/src/ir/IR.h
deleted file mode 100644
index 80a794002..000000000
--- a/src/ir/IR.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * IR.h
- *
- *  Created on: 06.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_IR_H_
-#define STORM_IR_IR_H_
-
-// Bundle all headers to make it easy to include them.
-#include "expressions/Expressions.h"
-#include "Assignment.h"
-#include "Update.h"
-#include "Command.h"
-#include "Variable.h"
-#include "BooleanVariable.h"
-#include "IntegerVariable.h"
-#include "Module.h"
-#include "StateReward.h"
-#include "TransitionReward.h"
-#include "RewardModel.h"
-#include "Program.h"
-
-#endif /* STORM_IR_IR_H_ */
diff --git a/src/ir/IntegerVariable.cpp b/src/ir/IntegerVariable.cpp
deleted file mode 100644
index b98b30d07..000000000
--- a/src/ir/IntegerVariable.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * IntegerVariable.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-#include <iostream>
-
-#include "IntegerVariable.h"
-#include "src/parser/prismparser/VariableState.h"
-
-namespace storm {
-    namespace ir {
-        
-        IntegerVariable::IntegerVariable() : lowerBound(), upperBound() {
-            // Nothing to do here.
-        }
-        
-        IntegerVariable::IntegerVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& lowerBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& upperBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue)
-        : Variable(localIndex, globalIndex, variableName, std::move(initialValue)), lowerBound(std::move(lowerBound)), upperBound(std::move(upperBound)) {
-            // Nothing to do here.
-        }
-        
-        IntegerVariable::IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
-        : Variable(oldVariable, newName, newGlobalIndex, renaming, variableState), lowerBound(oldVariable.lowerBound->clone(renaming, variableState)), upperBound(oldVariable.upperBound->clone(renaming, variableState)) {
-            // Nothing to do here.
-        }
-        
-        IntegerVariable::IntegerVariable(IntegerVariable const& otherVariable) : Variable(otherVariable.getLocalIndex(), otherVariable.getGlobalIndex(), otherVariable.getName(), nullptr), lowerBound(), upperBound() {
-            if (otherVariable.getInitialValue() != nullptr) {
-                setInitialValue(otherVariable.getInitialValue()->clone());
-            }
-            if (otherVariable.lowerBound != nullptr) {
-                lowerBound = otherVariable.lowerBound->clone();
-            }
-            if (otherVariable.upperBound != nullptr) {
-                upperBound = otherVariable.upperBound->clone();
-            }
-        }
-        
-        IntegerVariable& IntegerVariable::operator=(IntegerVariable const& otherVariable) {
-            if (this != &otherVariable) {
-                Variable::operator=(otherVariable);
-                this->lowerBound = otherVariable.lowerBound->clone();
-                this->upperBound = otherVariable.upperBound->clone();
-            }
-            
-            return *this;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& IntegerVariable::getLowerBound() const {
-            return this->lowerBound;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& IntegerVariable::getUpperBound() const {
-            return this->upperBound;
-        }
-        
-        std::string IntegerVariable::toString() const {
-            std::stringstream result;
-            result << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]";
-            if (this->getInitialValue() != nullptr) {
-                result << " init " + this->getInitialValue()->toString();
-            }
-            result << ";";
-            return result.str();
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/IntegerVariable.h b/src/ir/IntegerVariable.h
deleted file mode 100644
index 930e1d0b8..000000000
--- a/src/ir/IntegerVariable.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * IntegerVariable.h
- *
- *  Created on: 08.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_INTEGERVARIABLE_H_
-#define STORM_IR_INTEGERVARIABLE_H_
-
-#include <memory>
-
-#include "src/ir/Variable.h"
-#include "expressions/BaseExpression.h"
-
-namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing an integer variable.
-         */
-        class IntegerVariable : public Variable {
-        public:
-            /*!
-             * Default constructor. Creates an integer variable without a name and lower and upper bounds.
-             */
-            IntegerVariable();
-            
-            /*!
-             * Creates a boolean variable with the given name and the given initial value.
-             *
-             * @param localIndex A module-local unique index for the variable.
-             * @param globalIndex A globally unique index for the variable.
-             * @param variableName The name of the variable.
-             * @param lowerBound the lower bound of the domain of the variable.
-             * @param upperBound the upper bound of the domain of the variable.
-             * @param initialValue the expression that defines the initial value of the variable.
-             */
-            IntegerVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& lowerBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& upperBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue = nullptr);
-            
-            /*!
-             * Creates a copy of the given integer variable and performs the provided renaming.
-             *
-             * @param oldVariable The variable to copy.
-             * @param newName New name of this variable.
-             * @param newGlobalIndex The new global index of the variable.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param variableState An object knowing about the variables in the system.
-             */
-            IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
-            
-            /*!
-             * Performs a deep-copy of the given variable.
-             *
-             * @param otherVariable The variable to copy.
-             */
-            IntegerVariable(IntegerVariable const& otherVariable);
-            
-            IntegerVariable& operator=(IntegerVariable const& otherVariable);
-            
-            /*!
-             * Retrieves the lower bound for this integer variable.
-             * @returns the lower bound for this integer variable.
-             */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getLowerBound() const;
-            
-            /*!
-             * Retrieves the upper bound for this integer variable.
-             * @returns the upper bound for this integer variable.
-             */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getUpperBound() const;
-            
-            /*!
-             * Retrieves a string representation of this variable.
-             * @returns a string representation of this variable.
-             */
-            std::string toString() const;
-            
-        private:
-            // The lower bound of the domain of the variable.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> lowerBound;
-            
-            // The upper bound of the domain of the variable.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> upperBound;
-        };
-        
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_INTEGERVARIABLE_H_ */
diff --git a/src/ir/Program.h b/src/ir/Program.h
deleted file mode 100644
index 8ce96bc87..000000000
--- a/src/ir/Program.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Program.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_PROGRAM_H_
-#define STORM_IR_PROGRAM_H_
-
-#include <map>
-#include <vector>
-#include <memory>
-#include <set>
-#include <boost/container/flat_set.hpp>
-
-#include "expressions/BaseExpression.h"
-#include "expressions/BooleanConstantExpression.h"
-#include "expressions/IntegerConstantExpression.h"
-#include "expressions/DoubleConstantExpression.h"
-#include "Module.h"
-#include "RewardModel.h"
-
-namespace storm {
-    namespace ir {
-        
-        /*!
-         * A class representing a program.
-         */
-        class Program {
-        public:
-            
-            /*!
-             * An enum for the different model types.
-             */
-            enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP};
-            
-            /*!
-             * Default constructor. Creates an empty program.
-             */
-            Program();
-            
-            /*!
-             * Creates a program with the given model type, undefined constants, modules, rewards and labels.
-             *
-             * @param modelType The type of the model that this program gives rise to.
-             * @param booleanUndefinedConstantExpressions A map of undefined boolean constants to their
-             * expression nodes.
-             * @param integerUndefinedConstantExpressions A map of undefined integer constants to their
-             * expression nodes.
-             * @param doubleUndefinedConstantExpressions A map of undefined double constants to their
-             * expression nodes.
-             * @param globalBooleanVariables A list of global boolean variables.
-             * @param globalIntegerVariables A list of global integer variables.
-             * @param globalBooleanVariableToIndexMap A mapping from global boolean variable names to the index in the
-             * list of global boolean variables.
-             * @param globalIntegerVariableToIndexMap A mapping from global integer variable names to the index in the
-             * list of global integer variables.
-             * @param modules The modules of the program.
-             * @param rewards The reward models of the program.
-             * @param labels The labels defined for this model.
-             */
-            Program(ModelType modelType,
-                    std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& booleanUndefinedConstantExpressions,
-                    std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& integerUndefinedConstantExpressions,
-                    std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& doubleUndefinedConstantExpressions,
-                    std::vector<BooleanVariable> const& globalBooleanVariables,
-                    std::vector<IntegerVariable> const& globalIntegerVariables,
-                    std::map<std::string, uint_fast64_t> const& globalBooleanVariableToIndexMap,
-                    std::map<std::string, uint_fast64_t> const& globalIntegerVariableToIndexMap,
-                    std::vector<storm::ir::Module> const& modules,
-                    std::map<std::string, storm::ir::RewardModel> const& rewards,
-                    std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels);
-            
-            /*!
-             * Performs a deep-copy of the given program.
-             *
-             * @param otherProgram The program to copy.
-             */
-            Program(Program const& otherProgram);
-
-            /*!
-             * Performs a deep-copy of the given program and assigns it to the current one.
-             *
-             * @param otherProgram The program to assign.
-             */
-            Program& operator=(Program const& otherProgram);
-            
-            /*!
-             * Retrieves the number of modules in the program.
-             *
-             * @return The number of modules in the program.
-             */
-            uint_fast64_t getNumberOfModules() const;
-            
-            /*!
-             * Retrieves a reference to the module with the given index.
-             *
-             * @param index The index of the module to retrieve.
-             * @return The module with the given index.
-             */
-            storm::ir::Module const& getModule(uint_fast64_t index) const;
-            
-            /*!
-             * Retrieves the model type of the model.
-             *
-             * @return The type of the model.
-             */
-            ModelType getModelType() const;
-            
-            /*!
-             * Retrieves a string representation of this program.
-             *
-             * @return A string representation of this program.
-             */
-            std::string toString() const;
-            
-            /*!
-             * Retrieves a reference to the global boolean variable with the given index.
-             *
-             * @return A reference to the global boolean variable with the given index.
-             */
-            storm::ir::BooleanVariable const& getGlobalBooleanVariable(uint_fast64_t index) const;
-            
-            /*!
-             * Retrieves a reference to the global integer variable with the given index.
-             *
-             * @return A reference to the global integer variable with the given index.
-             */
-            storm::ir::IntegerVariable const& getGlobalIntegerVariable(uint_fast64_t index) const;
-            
-            /*!
-             * Retrieves the set of actions present in this module.
-             *
-             * @return The set of actions present in this module.
-             */
-            std::set<std::string> const& getActions() const;
-            
-            /*!
-             * Retrieves the indices of all modules within this program that contain commands that are labelled with the given
-             * action.
-             *
-             * @param action The name of the action the modules are supposed to possess.
-             * @return A set of indices of all matching modules.
-             */
-            std::set<uint_fast64_t> const& getModulesByAction(std::string const& action) const;
-            
-            /*!
-             * Retrieves the index of the module in which the given variable name was declared.
-             *
-             * @param variableName The name of the variable to search.
-             * @return The index of the module in which the given variable name was declared.
-             */
-            uint_fast64_t getModuleIndexForVariable(std::string const& variableName) const;
-            
-            /*!
-             * Retrieves the number of global boolean variables of the program.
-             *
-             * @return The number of global boolean variables of the program.
-             */
-            uint_fast64_t getNumberOfGlobalBooleanVariables() const;
-            
-            /*!
-             * Retrieves the number of global integer variables of the program.
-             *
-             * @return The number of global integer variables of the program.
-             */
-            uint_fast64_t getNumberOfGlobalIntegerVariables() const;
-            
-            /*!
-             * Retrieves the reward model with the given name.
-             *
-             * @param name The name of the reward model to return.
-             * @return The reward model with the given name.
-             */
-            storm::ir::RewardModel const& getRewardModel(std::string const& name) const;
-            
-            /*!
-             * Retrieves all labels that are defined by the probabilitic program.
-             *
-             * @return A set of labels that are defined in the program.
-             */
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& getLabels() const;
-            
-            /*!
-             * Retrieves whether the given constant name is an undefined boolean constant of the program.
-             *
-             * @return True if the given constant name is an undefined boolean constant of the program.
-             */
-            bool hasUndefinedBooleanConstant(std::string const& constantName) const;
-            
-            /*!
-             * Retrieves the expression associated with the given undefined boolean constant.
-             *
-             * @param constantName The name of the undefined boolean constant for which to retrieve the expression.
-             * @return The expression associated with the given undefined boolean constant.
-             */
-            std::unique_ptr<storm::ir::expressions::BooleanConstantExpression> const& getUndefinedBooleanConstantExpression(std::string const& constantName) const;
-            
-            /*!
-             * Retrieves whether the given constant name is an undefined integer constant of the program.
-             *
-             * @return True if the given constant name is an undefined integer constant of the program.
-             */
-            bool hasUndefinedIntegerConstant(std::string const& constantName) const;
-            
-            /*!
-             * Retrieves the expression associated with the given undefined integer constant.
-             *
-             * @param constantName The name of the undefined integer constant for which to retrieve the expression.
-             * @return The expression associated with the given undefined integer constant.
-             */
-            std::unique_ptr<storm::ir::expressions::IntegerConstantExpression> const& getUndefinedIntegerConstantExpression(std::string const& constantName) const;
-
-            /*!
-             * Retrieves whether the given constant name is an undefined double constant of the program.
-             *
-             * @return True if the given constant name is an undefined double constant of the program.
-             */
-            bool hasUndefinedDoubleConstant(std::string const& constantName) const;
-            
-            /*!
-             * Retrieves the expression associated with the given undefined double constant.
-             *
-             * @param constantName The name of the undefined double constant for which to retrieve the expression.
-             * @return The expression associated with the given undefined double constant.
-             */
-            std::unique_ptr<storm::ir::expressions::DoubleConstantExpression> const& getUndefinedDoubleConstantExpression(std::string const& constantName) const;
-            
-            /*!
-             * Retrieves the mapping of undefined boolean constant names to their expression objects.
-             *
-             * @return The mapping of undefined boolean constant names to their expression objects.
-             */
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& getBooleanUndefinedConstantExpressionsMap() const;
-
-            /*!
-             * Retrieves the mapping of undefined integer constant names to their expression objects.
-             *
-             * @return The mapping of undefined integer constant names to their expression objects.
-             */
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& getIntegerUndefinedConstantExpressionsMap() const;
-
-            /*!
-             * Retrieves the mapping of undefined double constant names to their expression objects.
-             *
-             * @return The mapping of undefined double constant names to their expression objects.
-             */
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& getDoubleUndefinedConstantExpressionsMap() const;
-            
-            /*!
-             * Retrieves the global index of the given boolean variable.
-             *
-             * @param variableName The name of the boolean variable whose index to retrieve.
-             */
-            uint_fast64_t getGlobalIndexOfBooleanVariable(std::string const& variableName) const;
-            
-            /*!
-             * Retrieves the global index of the integer boolean variable.
-             *
-             * @param variableName The name of the integer variable whose index to retrieve.
-             */
-            uint_fast64_t getGlobalIndexOfIntegerVariable(std::string const& variableName) const;
-            
-            /*!
-             * Deletes all commands with indices not in the given set from the program.
-             *
-             * @param indexSet The set of indices for which to keep the commands.
-             */
-            void restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
-        private:
-            // The type of the model.
-            ModelType modelType;
-            
-            // A map of undefined boolean constants to their expression nodes.
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> booleanUndefinedConstantExpressions;
-            
-            // A map of undefined integer constants to their expressions nodes.
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> integerUndefinedConstantExpressions;
-            
-            // A map of undefined double constants to their expressions nodes.
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> doubleUndefinedConstantExpressions;
-            
-            // A list of global boolean variables.
-            std::vector<BooleanVariable> globalBooleanVariables;
-            
-            // A list of global integer variables.
-            std::vector<IntegerVariable> globalIntegerVariables;
-            
-            // A mapping from global boolean variable names to their indices.
-            std::map<std::string, uint_fast64_t> globalBooleanVariableToIndexMap;
-            
-            // A mapping from global integer variable names to their indices.
-            std::map<std::string, uint_fast64_t> globalIntegerVariableToIndexMap;
-            
-            // The modules associated with the program.
-            std::vector<storm::ir::Module> modules;
-            
-            // The reward models associated with the program.
-            std::map<std::string, storm::ir::RewardModel> rewards;
-            
-            // The labels that are defined for this model.
-            std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> labels;
-            
-            // The set of actions present in this program.
-            std::set<std::string> actions;
-            
-            // A map of actions to the set of modules containing commands labelled with this action.
-            std::map<std::string, std::set<uint_fast64_t>> actionsToModuleIndexMap;
-            
-            // A mapping from variable names to the modules in which they were declared.
-            std::map<std::string, uint_fast64_t> variableToModuleIndexMap;
-        };
-        
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_PROGRAM_H_ */
diff --git a/src/ir/StateReward.cpp b/src/ir/StateReward.cpp
deleted file mode 100644
index ff3c815ce..000000000
--- a/src/ir/StateReward.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * StateReward.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "StateReward.h"
-
-namespace storm {
-    namespace ir {
-        
-        StateReward::StateReward() : statePredicate(), rewardValue() {
-            // Nothing to do here.
-        }
-        
-        StateReward::StateReward(std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue) : statePredicate(std::move(statePredicate)), rewardValue(std::move(rewardValue)) {
-            // Nothing to do here.
-        }
-        
-        StateReward::StateReward(StateReward const& otherReward) {
-            if (otherReward.statePredicate != nullptr) {
-                statePredicate = otherReward.statePredicate->clone();
-            }
-            if (otherReward.rewardValue != nullptr) {
-                rewardValue = otherReward.rewardValue->clone();
-            }
-        }
-        
-        StateReward& StateReward::operator=(StateReward const& otherReward) {
-            if (this != & otherReward) {
-                if (otherReward.statePredicate != nullptr) {
-                    this->statePredicate = otherReward.statePredicate->clone();
-                }
-                if (otherReward.rewardValue != nullptr) {
-                    this->rewardValue = otherReward.rewardValue->clone();
-                }
-            }
-            
-            return *this;
-        }
-        
-        std::string StateReward::toString() const {
-            std::stringstream result;
-            result << "\t" << statePredicate->toString() << ": " << rewardValue->toString() << ";";
-            return result.str();
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& StateReward::getStatePredicate() const {
-            return this->statePredicate;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& StateReward::getRewardValue() const {
-            return this->rewardValue;
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/TransitionReward.cpp b/src/ir/TransitionReward.cpp
deleted file mode 100644
index bd9664529..000000000
--- a/src/ir/TransitionReward.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * TransitionReward.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "TransitionReward.h"
-
-namespace storm {
-    namespace ir {
-        
-        TransitionReward::TransitionReward() : commandName(), statePredicate(), rewardValue() {
-            // Nothing to do here.
-        }
-        
-        TransitionReward::TransitionReward(std::string const& commandName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue) : commandName(commandName), statePredicate(std::move(statePredicate)), rewardValue(std::move(rewardValue)) {
-            // Nothing to do here.
-        }
-        
-        TransitionReward::TransitionReward(TransitionReward const& otherReward) : commandName(otherReward.commandName), statePredicate(), rewardValue() {
-            if (otherReward.statePredicate != nullptr) {
-                statePredicate = otherReward.statePredicate->clone();
-            }
-            if (otherReward.rewardValue != nullptr) {
-                rewardValue = otherReward.rewardValue->clone();
-            }
-        }
-        
-        TransitionReward& TransitionReward::operator=(TransitionReward const& otherReward) {
-            if (this != &otherReward) {
-                this->commandName = otherReward.commandName;
-                if (otherReward.statePredicate != nullptr) {
-                    this->statePredicate = otherReward.statePredicate->clone();
-                }
-                if (otherReward.rewardValue != nullptr) {
-                    this->rewardValue = otherReward.rewardValue->clone();
-                }
-            }
-            
-            return *this;
-        }
-        
-        std::string TransitionReward::toString() const {
-            std::stringstream result;
-            result << "\t[" << commandName << "] " << statePredicate->toString() << ": " << rewardValue->toString() << ";";
-            return result.str();
-        }
-        
-        std::string const& TransitionReward::getActionName() const {
-            return this->commandName;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& TransitionReward::getStatePredicate() const {
-            return this->statePredicate;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& TransitionReward::getRewardValue() const {
-            return this->rewardValue;
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/Update.cpp b/src/ir/Update.cpp
deleted file mode 100644
index aac7b3ca0..000000000
--- a/src/ir/Update.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Update.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "Update.h"
-#include "src/parser/prismparser/VariableState.h"
-#include "src/exceptions/OutOfRangeException.h"
-
-namespace storm {
-    namespace ir {
-        
-        Update::Update() : likelihoodExpression(), booleanAssignments(), integerAssignments(), globalIndex() {
-            // Nothing to do here.
-        }
-        
-        Update::Update(uint_fast64_t globalIndex, std::unique_ptr<storm::ir::expressions::BaseExpression>&& likelihoodExpression, std::map<std::string, storm::ir::Assignment> const& booleanAssignments, std::map<std::string, storm::ir::Assignment> const& integerAssignments)
-        : likelihoodExpression(std::move(likelihoodExpression)), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments), globalIndex(globalIndex) {
-            // Nothing to do here.
-        }
-        
-        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState) : globalIndex(newGlobalIndex) {
-            for (auto const& variableAssignmentPair : update.booleanAssignments) {
-                if (renaming.count(variableAssignmentPair.first) > 0) {
-                    this->booleanAssignments[renaming.at(variableAssignmentPair.first)] = Assignment(variableAssignmentPair.second, renaming, variableState);
-                } else {
-                    this->booleanAssignments[variableAssignmentPair.first] = Assignment(variableAssignmentPair.second, renaming, variableState);
-                }
-            }
-            for (auto const& variableAssignmentPair : update.integerAssignments) {
-                if (renaming.count(variableAssignmentPair.first) > 0) {
-                    this->integerAssignments[renaming.at(variableAssignmentPair.first)] = Assignment(variableAssignmentPair.second, renaming, variableState);
-                } else {
-                    this->integerAssignments[variableAssignmentPair.first] = Assignment(variableAssignmentPair.second, renaming, variableState);
-                }
-            }
-            this->likelihoodExpression = update.likelihoodExpression->clone(renaming, variableState);
-        }
-        
-        Update::Update(Update const& otherUpdate) : likelihoodExpression(), booleanAssignments(otherUpdate.booleanAssignments), integerAssignments(otherUpdate.integerAssignments), globalIndex(otherUpdate.globalIndex) {
-            if (otherUpdate.likelihoodExpression != nullptr) {
-                likelihoodExpression = otherUpdate.likelihoodExpression->clone();
-            }
-        }
-        
-        Update& Update::operator=(Update const& otherUpdate) {
-            if (this != &otherUpdate) {
-                if (otherUpdate.likelihoodExpression != nullptr) {
-                    this->likelihoodExpression = otherUpdate.likelihoodExpression->clone();
-                }
-                this->booleanAssignments = otherUpdate.booleanAssignments;
-                this->integerAssignments = otherUpdate.integerAssignments;
-                this->globalIndex = otherUpdate.globalIndex;
-            }
-            
-            return *this;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& Update::getLikelihoodExpression() const {
-            return likelihoodExpression;
-        }
-        
-        uint_fast64_t Update::getNumberOfBooleanAssignments() const {
-            return booleanAssignments.size();
-        }
-        
-        uint_fast64_t Update::getNumberOfIntegerAssignments() const {
-            return integerAssignments.size();
-        }
-        
-        std::map<std::string, storm::ir::Assignment> const& Update::getBooleanAssignments() const {
-            return booleanAssignments;
-        }
-        
-        std::map<std::string, storm::ir::Assignment> const& Update::getIntegerAssignments() const {
-            return integerAssignments;
-        }
-        
-        storm::ir::Assignment const& Update::getBooleanAssignment(std::string const& variableName) const {
-            auto variableAssignmentPair = booleanAssignments.find(variableName);
-            if (variableAssignmentPair == booleanAssignments.end()) {
-                throw storm::exceptions::OutOfRangeException() << "Cannot find boolean assignment for variable '"
-				<< variableName << "' in update " << this->toString() << ".";
-            }
-            
-            return variableAssignmentPair->second;
-        }
-        
-        storm::ir::Assignment const& Update::getIntegerAssignment(std::string const& variableName) const {
-            auto variableAssignmentPair = integerAssignments.find(variableName);
-            if (variableAssignmentPair == integerAssignments.end()) {
-                throw storm::exceptions::OutOfRangeException() << "Cannot find integer assignment for variable '"
-				<< variableName << "' in update " << this->toString() << ".";
-            }
-            
-            return variableAssignmentPair->second;
-        }
-        
-        uint_fast64_t Update::getGlobalIndex() const {
-            return this->globalIndex;
-        }
-        
-        std::string Update::toString() const {
-            std::stringstream result;
-            result << likelihoodExpression->toString() << " : ";
-            uint_fast64_t i = 0;
-            for (auto const& assignment : booleanAssignments) {
-                result << assignment.second.toString();
-                if (i < booleanAssignments.size() - 1 || integerAssignments.size() > 0) {
-                    result << " & ";
-                }
-                ++i;
-            }
-            i = 0;
-            for (auto const& assignment : integerAssignments) {
-                result << assignment.second.toString();
-                if (i < integerAssignments.size() - 1) {
-                    result << " & ";
-                }
-                ++i;
-            }
-            return result.str();
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/Variable.cpp b/src/ir/Variable.cpp
deleted file mode 100644
index 83cb2a33a..000000000
--- a/src/ir/Variable.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Variable.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-#include <map>
-#include <iostream>
-
-#include "Variable.h"
-#include "src/parser/prismparser/VariableState.h"
-
-namespace storm {
-    namespace ir {
-        
-        Variable::Variable() : localIndex(0), globalIndex(0), variableName(), initialValue() {
-            // Nothing to do here.
-        }
-        
-        Variable::Variable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue)
-        : localIndex(localIndex), globalIndex(globalIndex), variableName(variableName), initialValue(std::move(initialValue)) {
-            // Nothing to do here.
-        }
-        
-        Variable::Variable(Variable const& otherVariable) : localIndex(otherVariable.localIndex), globalIndex(otherVariable.globalIndex), variableName(otherVariable.variableName), initialValue() {
-            if (otherVariable.initialValue != nullptr) {
-                initialValue = otherVariable.initialValue->clone();
-            }
-        }
-        
-        Variable::Variable(Variable const& var, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
-        : localIndex(var.getLocalIndex()), globalIndex(newGlobalIndex), variableName(newName), initialValue() {
-            if (var.initialValue != nullptr) {
-                this->initialValue = var.initialValue->clone(renaming, variableState);
-            }
-        }
-        
-        Variable& Variable::operator=(Variable const& otherVariable) {
-            if (this != &otherVariable) {
-                this->localIndex = otherVariable.localIndex;
-                this->globalIndex = otherVariable.globalIndex;
-                this->variableName = otherVariable.variableName;
-                if (otherVariable.initialValue != nullptr) {
-                    this->initialValue = otherVariable.initialValue->clone();
-                }
-            }
-            
-            return *this;
-        }
-        
-        std::string const& Variable::getName() const {
-            return variableName;
-        }
-        
-        uint_fast64_t Variable::getGlobalIndex() const {
-            return globalIndex;
-        }
-        
-        uint_fast64_t Variable::getLocalIndex() const {
-            return localIndex;
-        }
-        
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& Variable::getInitialValue() const {
-            return initialValue;
-        }
-        
-        void Variable::setInitialValue(std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue) {
-            this->initialValue = std::move(initialValue);
-        }
-        
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/Variable.h b/src/ir/Variable.h
deleted file mode 100644
index 53b2f3b98..000000000
--- a/src/ir/Variable.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Variable.h
- *
- *  Created on: 06.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_VARIABLE_H_
-#define STORM_IR_VARIABLE_H_
-
-#include <string>
-#include <memory>
-
-#include "expressions/BaseExpression.h"
-
-namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing a untyped variable.
-         */
-        class Variable {
-        public:
-            /*!
-             * Default constructor. Creates an unnamed, untyped variable without initial value.
-             */
-            Variable();
-            
-            /*!
-             * Creates an untyped variable with the given name and initial value.
-             *
-             * @param localIndex A module-local index for the variable.
-             * @param globalIndex A globally unique (among the variables of equal type) index for the variable.
-             * @param variableName the name of the variable.
-             * @param initialValue the expression that defines the initial value of the variable.
-             */
-            Variable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue = nullptr);
-            
-            /*!
-             * Creates a copy of the given variable and performs the provided renaming.
-             *
-             * @param oldVariable The variable to copy.
-             * @param newName New name of this variable.
-             * @param newGlobalIndex The new global index of the variable.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param variableState An object knowing about the variables in the system.
-             */
-            Variable(Variable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
-            
-            /*!
-             * Creates a deep-copy of the given variable.
-             *
-             * @param otherVariable The variable to copy.
-             */
-            Variable(Variable const& otherVariable);
-            
-            /*!
-             * Creates a deep-copy of the given variable and assigns it to the current one.
-             */
-            Variable& operator=(Variable const& otherVariable);
-            
-            /*!
-             * Retrieves the name of the variable.
-             *
-             * @return The name of the variable.
-             */
-            std::string const& getName() const;
-            
-            /*!
-             * Retrieves the global index of the variable, i.e. the index in all variables of equal type
-             * of all modules.
-             *
-             * @return The global index of the variable.
-             */
-            uint_fast64_t getGlobalIndex() const;
-            
-            /*!
-             * Retrieves the global index of the variable, i.e. the index in all variables of equal type in
-             * the same module.
-             *
-             * @return The local index of the variable.
-             */
-            uint_fast64_t getLocalIndex() const;
-            
-            /*!
-             * Retrieves the expression defining the initial value of the variable.
-             *
-             * @return The expression defining the initial value of the variable.
-             */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getInitialValue() const;
-            
-            /*!
-             * Sets the initial value to the given expression.
-             *
-             * @param initialValue The new initial value.
-             */
-            void setInitialValue(std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue);
-            
-        private:
-            // A unique (among the variables of equal type) index for the variable inside its module.
-            uint_fast64_t localIndex;
-
-            // A unique (among the variables of equal type) index for the variable over all modules.
-            uint_fast64_t globalIndex;
-            
-            // The name of the variable.
-            std::string variableName;
-            
-            // The expression defining the initial value of the variable.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> initialValue;
-        };
-        
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_VARIABLE_H_ */
diff --git a/src/ir/expressions/BaseExpression.cpp b/src/ir/expressions/BaseExpression.cpp
deleted file mode 100644
index 66771d6b0..000000000
--- a/src/ir/expressions/BaseExpression.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * BaseExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include "BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            BaseExpression::BaseExpression() : type(undefined) {
-                // Nothing to do here.
-            }
-            
-            BaseExpression::BaseExpression(ReturnType type) : type(type) {
-                // Nothing to do here.
-            }
-            
-            BaseExpression::BaseExpression(BaseExpression const& baseExpression) : type(baseExpression.type) {
-                // Nothing to do here.
-            }
-            
-            BaseExpression::~BaseExpression() {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> BaseExpression::substitute(std::unique_ptr<BaseExpression>&& expression, std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
-                BaseExpression* result = expression->performSubstitution(substitution);
-                
-                if (result != expression.get()) {
-                    return std::unique_ptr<BaseExpression>(result);
-                } else {
-                    return std::move(expression);
-                }
-            }
-            
-            int_fast64_t BaseExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (type != int_) {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '"
-                    << this->getTypeName() << "' as 'int'.";
-                }
-                throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '"
-                << this->getTypeName() << " because evaluation implementation is missing.";
-            }
-            
-            bool BaseExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (type != bool_) {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '"
-                    << this->getTypeName() << "' as 'bool'.";
-                }
-                throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '"
-                << this->getTypeName() << " because evaluation implementation is missing.";
-            }
-            
-            double BaseExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (type != double_ && type != int_) {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '"
-                    << this->getTypeName() << "' as 'double'.";
-                }
-                throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '"
-                << this->getTypeName() << " because evaluation implementation is missing.";
-            }
-            
-            std::string BaseExpression::getTypeName() const {
-                switch(type) {
-                    case bool_: return std::string("bool");
-                    case int_: return std::string("int");
-                    case double_: return std::string("double");
-                    default: return std::string("undefined");
-                }
-            }
-            
-            BaseExpression::ReturnType BaseExpression::getType() const {
-                return type;
-            }
-            
-            BaseExpression* BaseExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
-                return this;
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h
deleted file mode 100644
index 948ed9d88..000000000
--- a/src/ir/expressions/BaseExpression.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * BaseExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_
-
-#include <string>
-#include <vector>
-#include <map>
-#include <memory>
-
-#include "src/exceptions/ExpressionEvaluationException.h"
-#include "src/exceptions/NotImplementedException.h"
-#include "ExpressionVisitor.h"
-
-namespace storm {
-    
-    // Forward-declare VariableState.
-	namespace parser {
-		namespace prism {
-			class VariableState;
-		} // namespace prismparser
-	} // namespace parser
-    
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * The base class for all expressions.
-             */
-            class BaseExpression {
-            public:
-                // Forward declare friend classes to allow access to substitute.
-                friend class BinaryExpression;
-                friend class UnaryExpression;
-
-                /*!
-                 * Each node in an expression tree has a uniquely defined type from this enum.
-                 */
-                enum ReturnType {undefined, bool_, int_, double_};
-                
-                /*!
-                 * Creates an expression with undefined type.
-                 */
-                BaseExpression();
-                
-                /*!
-                 * Creates an expression with the given type.
-                 *
-                 * @param type The type of the expression.
-                 */
-                BaseExpression(ReturnType type);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param baseExpression The expression to copy.
-                 */
-                BaseExpression(BaseExpression const& baseExpression);
-                
-                /*!
-                 * Destructor.
-                 */
-                virtual ~BaseExpression();
-                
-                /*!
-                 * Performes a deep-copy of the expression.
-                 *
-                 * @return A deep-copy of the expression.
-                 */
-                virtual std::unique_ptr<BaseExpression> clone() const = 0;
-                
-                /*!
-                 * Copies the expression tree underneath (including) the current node and performs the provided renaming.
-                 *
-                 * @param renaming A mapping from identifier names to strings they are to be replaced with.
-                 * @param variableState An object knowing about the global variable state.
-                 */
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const = 0;
-                
-                /*!
-                 * Performs the given substitution by replacing each variable in the given expression that is a key in
-                 * the map by a copy of the mapped expression.
-                 *
-                 * @param expression The expression in which to perform the substitution.
-                 * @param substitution The substitution to apply.
-                 * @return The resulting expression.
-                 */
-                static std::unique_ptr<BaseExpression> substitute(std::unique_ptr<BaseExpression>&& expression, std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution);
-                
-                /*!
-                 * Retrieves the value of the expression as an integer given the provided variable valuation.
-                 *
-                 * @param variableValues The variable valuation under which to evaluate the expression. If set to null,
-                 * constant expressions can be evaluated without variable values. However, upon encountering a variable
-                 * expression an expression is thrown, because evaluation is impossible without the variable values then.
-                 * @return The value of the expression as an integer.
-                 */
-                virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const;
-                
-                /*!
-                 * Retrieves the value of the expression as a boolean given the provided variable valuation.
-                 *
-                 * @param variableValues The variable valuation under which to evaluate the expression. If set to null,
-                 * constant expressions can be evaluated without variable values. However, upon encountering a variable
-                 * expression an expression is thrown, because evaluation is impossible without the variable values then.
-                 * @return The value of the expression as a boolean.
-                 */
-                virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const;
-                
-                /*!
-                 * Retrieves the value of the expression as a double given the provided variable valuation.
-                 *
-                 * @param variableValues The variable valuation under which to evaluate the expression. If set to null,
-                 * constant expressions can be evaluated without variable values. However, upon encountering a variable
-                 * expression an expression is thrown, because evaluation is impossible without the variable values then.
-                 * @return The value of the expression as a double.
-                 */
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const;
-                
-                /*!
-                 * Acceptor method for visitor pattern.
-                 *
-                 * @param visitor The visitor that is supposed to visit each node of the expression tree.
-                 */
-                virtual void accept(ExpressionVisitor* visitor) = 0;
-                
-                /*!
-                 * Retrieves a string representation of the expression tree underneath the current node.
-                 *
-                 * @return A string representation of the expression tree underneath the current node.
-                 */
-                virtual std::string toString() const = 0;
-                
-                /*!
-                 * Retrieves a string representation of the type to which this node evaluates.
-                 *
-                 * @return A string representation of the type to which this node evaluates.
-                 */
-                std::string getTypeName() const;
-                
-                /*!
-                 * Retrieves the type to which the node evaluates.
-                 *
-                 * @return The type to which the node evaluates.
-                 */
-                ReturnType getType() const;
-                
-            protected:
-                /*!
-                 * Performs the given substitution on the expression, i.e. replaces all variables whose names are keys
-                 * of the map by a copy of the expression they are associated with in the map. This is intended as a helper
-                 * function for substitute.
-                 *
-                 * @param substitution The substitution to perform
-                 */
-                virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution);
-                
-            private:
-                // The type to which this node evaluates.
-                ReturnType type;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.cpp b/src/ir/expressions/BinaryBooleanFunctionExpression.cpp
deleted file mode 100644
index 83cb1d82f..000000000
--- a/src/ir/expressions/BinaryBooleanFunctionExpression.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * BinaryBooleanFunctionExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "BinaryBooleanFunctionExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType)
-            : BinaryExpression(bool_, std::move(left), std::move(right)), functionType(functionType) {
-                // Nothing to do here.
-            }
-            
-            BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& binaryBooleanFunctionExpression)
-            : BinaryExpression(binaryBooleanFunctionExpression), functionType(binaryBooleanFunctionExpression.functionType) {
-                // Nothing to do here.
-            }
-
-            std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getLeft()->clone(), this->getRight()->clone(), functionType));
-            }
-            
-            std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getLeft()->clone(renaming, variableState), this->getRight()->clone(renaming, variableState), this->functionType));
-            }
-            
-            bool BinaryBooleanFunctionExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                bool resultLeft = this->getLeft()->getValueAsBool(variableValues);
-                bool resultRight = this->getRight()->getValueAsBool(variableValues);
-                switch(functionType) {
-                    case AND: return resultLeft & resultRight; break;
-                    case OR: return resultLeft | resultRight; break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown boolean binary operator: '" << functionType << "'.";
-                }
-            }
-            
-            BinaryBooleanFunctionExpression::FunctionType BinaryBooleanFunctionExpression::getFunctionType() const {
-                return functionType;
-            }
-            
-            void BinaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string BinaryBooleanFunctionExpression::toString() const {
-                std::stringstream result;
-                result << "(" << this->getLeft()->toString();
-                switch (functionType) {
-                    case AND: result << " & "; break;
-                    case OR: result << " | "; break;
-                }
-                result << this->getRight()->toString() << ")";
-                
-                return result.str();
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h
deleted file mode 100644
index b0cec5906..000000000
--- a/src/ir/expressions/BinaryBooleanFunctionExpression.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * BinaryBooleanFunctionExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
-
-#include "BinaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a binary function expression of boolean type.
-             */
-            class BinaryBooleanFunctionExpression : public BinaryExpression {
-            public:
-                /*!
-                 * An enum type specifying the different functions applicable.
-                 */
-                enum FunctionType {AND, OR};
-                
-                /*!
-                 * Creates a binary boolean function expression tree node with the given children and function type.
-                 *
-                 * @param left The left child of the node.
-                 * @param right The right child of the node.
-                 * @param functionType The operator that is to be applied to the two children.
-                 */
-                BinaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param binaryBooleanFunctionExpression The expression to copy.
-                 */
-                BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& binaryBooleanFunctionExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                /*!
-                 * Retrieves the operator that is associated with this node.
-                 *
-                 * @param The operator that is associated with this node.
-                 */
-                FunctionType getFunctionType() const;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                                
-            private:
-                // The operator that is associated with this node.
-                FunctionType functionType;
-            };
-            
-        } // namespace expressions
-    } // namespace ir    
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryExpression.cpp b/src/ir/expressions/BinaryExpression.cpp
deleted file mode 100644
index 417cc9301..000000000
--- a/src/ir/expressions/BinaryExpression.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * BinaryBooleanFunctionExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include "BinaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            BinaryExpression::BinaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right)
-            : BaseExpression(type), left(std::move(left)), right(std::move(right)) {
-                // Nothing to do here.
-            }
-            
-            BinaryExpression::BinaryExpression(BinaryExpression const& binaryExpression) : BaseExpression(binaryExpression.getType()), left(binaryExpression.left->clone()), right(binaryExpression.right->clone()) {
-                // Nothing to do here.
-            }
-
-            BaseExpression* BinaryExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
-                // Get the new left successor recursively.
-                BaseExpression* newLeftSuccessor = left->performSubstitution(substitution);
-                
-                // If the left successor changed, we need to update it. If it did not change, this must not be executed,
-                // because assigning to the unique_ptr will destroy the current successor immediately.
-                if (newLeftSuccessor != left.get()) {
-                    left = std::unique_ptr<BaseExpression>(newLeftSuccessor);
-                }
-                
-                // Now do the same thing for the right successor.
-                BaseExpression* newRightSuccessor = right->performSubstitution(substitution);
-                if (newRightSuccessor != right.get()) {
-                    right = std::unique_ptr<BaseExpression>(newRightSuccessor);
-                }
-            
-                return this;
-            }
-            
-            std::unique_ptr<BaseExpression> const& BinaryExpression::getLeft() const {
-                return left;
-            }
-            
-            std::unique_ptr<BaseExpression> const& BinaryExpression::getRight() const {
-                return right;
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/BinaryExpression.h b/src/ir/expressions/BinaryExpression.h
deleted file mode 100644
index 1d6560863..000000000
--- a/src/ir/expressions/BinaryExpression.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * BinaryExpression.h
- *
- *  Created on: 27.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_
-
-#include "src/ir/expressions/BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a generic binary expression.
-             */
-            class BinaryExpression : public BaseExpression {
-            public:
-                /*!
-                 * Constructs a binary expression with the given type and children.
-                 * @param type The type of the binary expression.
-                 * @param left The left child of the binary expression.
-                 * @param right The right child of the binary expression.
-                 */
-                BinaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param binaryExpression The expression to copy.
-                 */
-                BinaryExpression(BinaryExpression const& binaryExpression);
-                                
-                /*!
-                 * Retrieves the left child of the expression node.
-                 *
-                 * @return The left child of the expression node.
-                 */
-                std::unique_ptr<BaseExpression> const& getLeft() const;
-                
-                /*!
-                 * Retrieves the right child of the expression node.
-                 *
-                 * @return The right child of the expression node.
-                 */
-                std::unique_ptr<BaseExpression> const& getRight() const;
-                
-            protected:
-                virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) override;
-                
-            private:
-                // The left child of the binary expression.
-                std::unique_ptr<BaseExpression> left;
-                
-                // The right child of the binary expression.
-                std::unique_ptr<BaseExpression> right;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.cpp b/src/ir/expressions/BinaryNumericalFunctionExpression.cpp
deleted file mode 100644
index a80e04ae4..000000000
--- a/src/ir/expressions/BinaryNumericalFunctionExpression.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * BinaryBooleanFunctionExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-#include <algorithm>
-
-#include "BinaryNumericalFunctionExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType)
-            : BinaryExpression(type, std::move(left), std::move(right)), functionType(functionType) {
-                // Nothing to do here.
-            }
-            
-            BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& binaryNumericalFunctionExpression)
-            : BinaryExpression(binaryNumericalFunctionExpression), functionType(binaryNumericalFunctionExpression.functionType) {
-                // Nothing to do here.
-            }
-
-            std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getType(), this->getLeft()->clone(), this->getRight()->clone(), functionType));
-            }
-
-            std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getType(), this->getLeft()->clone(renaming, variableState), this->getRight()->clone(renaming, variableState), this->functionType));
-            }
-            
-            BinaryNumericalFunctionExpression::FunctionType BinaryNumericalFunctionExpression::getFunctionType() const {
-                return functionType;
-            }
-            
-            int_fast64_t BinaryNumericalFunctionExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != int_) {
-                    BaseExpression::getValueAsInt(variableValues);
-                }
-                
-                int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues);
-                int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues);
-                switch(functionType) {
-                    case PLUS: return resultLeft + resultRight; break;
-                    case MINUS: return resultLeft - resultRight; break;
-                    case TIMES: return resultLeft * resultRight; break;
-                    case DIVIDE: return resultLeft / resultRight; break;
-                    case MIN: return std::min(resultLeft, resultRight); break;
-                    case MAX: return std::max(resultLeft, resultRight); break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown numeric binary operator: '" << functionType << "'.";
-                }
-            }
-                        
-            double BinaryNumericalFunctionExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != double_ && this->getType() != int_) {
-                    BaseExpression::getValueAsDouble(variableValues);
-                }
-                
-                double resultLeft = this->getLeft()->getValueAsDouble(variableValues);
-                double resultRight = this->getRight()->getValueAsDouble(variableValues);
-                switch(functionType) {
-                    case PLUS: return resultLeft + resultRight; break;
-                    case MINUS: return resultLeft - resultRight; break;
-                    case TIMES: return resultLeft * resultRight; break;
-                    case DIVIDE: return resultLeft / resultRight; break;
-                    case MIN: return std::min(resultLeft, resultRight); break;
-                    case MAX: return std::max(resultLeft, resultRight); break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown numeric binary operator: '" << functionType << "'.";
-                }
-            }
-            
-            void BinaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string BinaryNumericalFunctionExpression::toString() const {
-                std::stringstream result;
-                switch (functionType) {
-                    case PLUS: result << "(" << this->getLeft()->toString() << " + " << this->getRight()->toString() << ")"; break;
-                    case MINUS: result << "(" << this->getLeft()->toString() << " - " << this->getRight()->toString() << ")"; break;
-                    case TIMES: result << "(" << this->getLeft()->toString() << " * " << this->getRight()->toString() << ")"; break;
-                    case DIVIDE: result << "(" << this->getLeft()->toString() << " / " << this->getRight()->toString() << ")"; break;
-                    case MIN: result << "min(" << this->getLeft()->toString() << ", " << this->getRight()->toString() << ")"; break;
-                    case MAX: result << "max(" << this->getLeft()->toString() << ", " << this->getRight()->toString() << ")"; break;
-                }
-                return result.str();
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h
deleted file mode 100644
index 846ceb99a..000000000
--- a/src/ir/expressions/BinaryNumericalFunctionExpression.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * BinaryFunctionExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BINARYFUNCTIONEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BINARYFUNCTIONEXPRESSION_H_
-
-#include "src/ir/expressions/BinaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a binary function expression of numerical type.
-             */
-            class BinaryNumericalFunctionExpression : public BinaryExpression {
-            public:
-                /*!
-                 * An enum type specifying the different functions applicable.
-                 */
-                enum FunctionType {PLUS, MINUS, TIMES, DIVIDE, MIN, MAX};
-                
-                /*!
-                 * Creates a binary numerical function expression with the given type, children and function type.
-                 *
-                 * @param type The type of the expression tree node.
-                 * @param left The left child of the expression tree node.
-                 * @param right The right child of the  expression tree node.
-                 * @param functionType The function that is applied to the children of this node.
-                 */
-                BinaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType);
-                
-                /*!
-                 * Performs a deep-copy of the given expression.
-                 *
-                 * @param binaryNumericalFunctionExpression The expression to copy.
-                 */
-                BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& binaryNumericalFunctionExpression);
-
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                /*!
-                 * Retrieves the operator that is associated with this node.
-                 *
-                 * @param The operator that is associated with this node.
-                 */
-                FunctionType getFunctionType() const;
-                
-                virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                
-            private:
-                // The operator that is associated with this node.
-                FunctionType functionType;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BINARYFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryRelationExpression.cpp b/src/ir/expressions/BinaryRelationExpression.cpp
deleted file mode 100644
index 5c08e7f33..000000000
--- a/src/ir/expressions/BinaryRelationExpression.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * BinaryBooleanFunctionExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "BinaryRelationExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            BinaryRelationExpression::BinaryRelationExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, RelationType relationType)
-            : BinaryExpression(bool_, std::move(left), std::move(right)), relationType(relationType) {
-                // Nothing to do here.
-            }
-            
-            BinaryRelationExpression::BinaryRelationExpression(BinaryRelationExpression const& binaryRelationExpression)
-            : BinaryExpression(binaryRelationExpression), relationType(binaryRelationExpression.relationType) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> BinaryRelationExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(this->getLeft()->clone(), this->getRight()->clone(), relationType));
-            }
-
-            std::unique_ptr<BaseExpression> BinaryRelationExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(this->getLeft()->clone(renaming, variableState), this->getRight()->clone(renaming, variableState), this->relationType));
-            }
-            
-            bool BinaryRelationExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues);
-                int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues);
-                switch(relationType) {
-                    case EQUAL: return resultLeft == resultRight; break;
-                    case NOT_EQUAL: return resultLeft != resultRight; break;
-                    case LESS: return resultLeft < resultRight; break;
-                    case LESS_OR_EQUAL: return resultLeft <= resultRight; break;
-                    case GREATER: return resultLeft > resultRight; break;
-                    case GREATER_OR_EQUAL: return resultLeft >= resultRight; break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown boolean binary relation: '" << relationType << "'.";
-                }
-            }
-            
-            BinaryRelationExpression::RelationType BinaryRelationExpression::getRelationType() const {
-                return relationType;
-            }
-            
-            void BinaryRelationExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string BinaryRelationExpression::toString() const {
-                std::stringstream result;
-                result << "(" << this->getLeft()->toString();
-                switch (relationType) {
-                    case EQUAL: result << " = "; break;
-                    case NOT_EQUAL: result << " != "; break;
-                    case LESS: result << " < "; break;
-                    case LESS_OR_EQUAL: result << " <= "; break;
-                    case GREATER: result << " > "; break;
-                    case GREATER_OR_EQUAL: result << " >= "; break;
-                }
-                result << this->getRight()->toString() << ")";
-                
-                return result.str();
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h
deleted file mode 100644
index 873cbe5bf..000000000
--- a/src/ir/expressions/BinaryRelationExpression.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * BinaryRelationExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
-
-#include "src/ir/expressions/BinaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a binary relation expression of boolean type.
-             */
-            class BinaryRelationExpression : public BinaryExpression {
-            public:
-                /*!
-                 * An enum type specifying the different relations applicable.
-                 */
-                enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL};
-                
-                /*!
-                 * Creates a binary relation expression tree node with the given children and relation type.
-                 *
-                 * @param left The left child of the binary expression.
-                 * @param right The right child of the binary expression.
-                 * @param relationType The type of the relation associated with this node.
-                 */
-                BinaryRelationExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, RelationType relationType);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param binaryRelationExpression The expression to copy.
-                 */
-                BinaryRelationExpression(BinaryRelationExpression const& binaryRelationExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                /*!
-                 * Retrieves the relation that is associated with this node.
-                 *
-                 * @param The relation that is associated with this node.
-                 */
-                RelationType getRelationType() const;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                
-            private:
-                // The relation operator associated with this node.
-                RelationType relationType;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/BooleanConstantExpression.cpp b/src/ir/expressions/BooleanConstantExpression.cpp
deleted file mode 100644
index 2022e8796..000000000
--- a/src/ir/expressions/BooleanConstantExpression.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * BooleanConstantExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include "BooleanConstantExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression<bool>(bool_, constantName) {
-                // Nothing to do here.
-            }
-            
-            BooleanConstantExpression::BooleanConstantExpression(BooleanConstantExpression const& booleanConstantExpression) : ConstantExpression(booleanConstantExpression) {
-                // Nothing to do here.
-            }
-
-            std::unique_ptr<BaseExpression> BooleanConstantExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new BooleanConstantExpression(*this));
-            }
-
-            std::unique_ptr<BaseExpression> BooleanConstantExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new BooleanConstantExpression(*this));
-            }
-            
-            bool BooleanConstantExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (!this->isDefined()) {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                    << "Boolean constant '" << this->getConstantName() << "' is undefined.";
-                } else {
-                    return this->getValue();
-                }
-            }
-            
-            void BooleanConstantExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/BooleanConstantExpression.h b/src/ir/expressions/BooleanConstantExpression.h
deleted file mode 100644
index 4838ba595..000000000
--- a/src/ir/expressions/BooleanConstantExpression.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * BooleanConstantExpression.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
-
-#include "ConstantExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a boolean constant expression.
-             */
-            class BooleanConstantExpression : public ConstantExpression<bool> {
-            public:
-                /*!
-                 * Creates a boolean constant expression with the given constant name.
-                 *
-                 * @param constantName The name of the constant to use.
-                 */
-                BooleanConstantExpression(std::string const& constantName);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param booleanConstantExpression The expression to copy.
-                 */
-                BooleanConstantExpression(BooleanConstantExpression const& booleanConstantExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ */
diff --git a/src/ir/expressions/BooleanLiteralExpression.cpp b/src/ir/expressions/BooleanLiteralExpression.cpp
deleted file mode 100644
index 89e6b7876..000000000
--- a/src/ir/expressions/BooleanLiteralExpression.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * BooleanLiteralExpression.cpp
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#include "BooleanLiteralExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            BooleanLiteralExpression::BooleanLiteralExpression(bool value) : BaseExpression(bool_), value(value) {
-                // Nothing to do here.
-            }
-            
-            BooleanLiteralExpression::BooleanLiteralExpression(BooleanLiteralExpression const& booleanLiteralExpression)
-            : BaseExpression(booleanLiteralExpression), value(booleanLiteralExpression.value) {
-                // Nothing to do here.
-            }
-
-            std::unique_ptr<BaseExpression> BooleanLiteralExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(*this));
-            }
-                                                       
-            std::unique_ptr<BaseExpression> BooleanLiteralExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(this->value));
-            }
-            
-            bool BooleanLiteralExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                return value;
-            }
-            
-            void BooleanLiteralExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string BooleanLiteralExpression::toString() const {
-                if (value) {
-                    return std::string("true");
-                } else {
-                    return std::string("false");
-                }
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/BooleanLiteralExpression.h b/src/ir/expressions/BooleanLiteralExpression.h
deleted file mode 100644
index 1fb747a78..000000000
--- a/src/ir/expressions/BooleanLiteralExpression.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * BooleanLiteralExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
-
-#include "src/ir/expressions/BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a boolean literal.
-             */
-            class BooleanLiteralExpression : public BaseExpression {
-            public:
-                /*!
-                 * Creates a boolean literal expression with the given value.
-                 *
-                 * @param value The value for the boolean literal.
-                 */
-                BooleanLiteralExpression(bool value);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param booleanLiteralExpression The expression to copy.
-                 */
-                BooleanLiteralExpression(BooleanLiteralExpression const& booleanLiteralExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                
-            private:
-                // The value of the boolean literal.
-                bool value;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_ */
diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h
deleted file mode 100644
index dc1763c33..000000000
--- a/src/ir/expressions/ConstantExpression.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * ConstantExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_CONSTANTEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_CONSTANTEXPRESSION_H_
-
-#include "BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            // A struct for storing whether the constant was defined and if so, what value it holds.
-            template<class T>
-            struct ConstantDefinitionStruct {
-                /*!
-                 * Constructs a structure indicating that the constant has been defined with the given value.
-                 *
-                 * @param value The value with which the constant was defined.
-                 */
-                ConstantDefinitionStruct(T value) : value(value), defined(true) {
-                   // Nothing to do here. 
-                }
-                
-                /*!
-                 * Constructs a structure indicating that the constant has not yet been defined.
-                 *
-                 * @param value The value with which the constant was defined.
-                 */
-                ConstantDefinitionStruct() : value(), defined(false) {
-                    // Nothing to do here. 
-                }
-                
-                T value;
-                bool defined;
-            };
-            
-            /*!
-             * A class representing a generic constant expression.
-             */
-            template<class T>
-            class ConstantExpression : public BaseExpression {
-            public:
-                /*!
-                 * Constructs a constant expression of the given type with the given constant name.
-                 *
-                 * @param type The type of the constant.
-                 * @param constantName The name of the constant.
-                 */
-                ConstantExpression(ReturnType type, std::string const& constantName) : BaseExpression(type), constantName(constantName), valueStructPointer(new ConstantDefinitionStruct<T>()) {
-                    // Nothing to do here.
-                }
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param constantExpression The expression to copy.
-                 */
-                ConstantExpression(ConstantExpression const& constantExpression) : BaseExpression(constantExpression), constantName(constantExpression.constantName), valueStructPointer(constantExpression.valueStructPointer) {
-                    // Nothing to do here.
-                }
-                
-                /*!
-                 * Retrieves the name of the constant.
-                 *
-                 * @return The name of the constant.
-                 */
-                std::string const& getConstantName() const {
-                    return constantName;
-                }
-                
-                virtual std::string toString() const override {
-                    std::stringstream result;
-                    if (this->valueStructPointer->defined) {
-                        result << this->valueStructPointer->value;
-                    } else {
-                        result << this->getConstantName();
-                    }
-                    return result.str();
-                }
-                
-                /*!
-                 * Retrieves whether the constant is defined or not.
-                 *
-                 * @return True if the constant is defined.
-                 */
-                bool isDefined() const {
-                    return this->valueStructPointer->defined;
-                }
-                
-                /*!
-                 * Retrieves the value of the constant if it is defined.
-                 */
-                T getValue() const {
-                    return this->valueStructPointer->value;
-                }
-                
-                /*!
-                 * Defines the constant using the given value.
-                 *
-                 * @param value The value to use for defining the constant.
-                 */
-                void define(T value) {
-                    this->valueStructPointer->defined = true;
-                    this->valueStructPointer->value = value;
-                }
-                
-                /*!
-                 * Undefines the value that was previously set for this constant (if any).
-                 */
-                void undefine() {
-                    this->valueStructPointer->defined = false;
-                    this->valueStructPointer->value = T();
-                }
-                
-            private:
-                // The name of the constant.
-                std::string constantName;
-                
-                // The definedness status and (if applicable) the value of the constant.
-                std::shared_ptr<ConstantDefinitionStruct<T>> valueStructPointer;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_CONSTANTEXPRESSION_H_ */
diff --git a/src/ir/expressions/DoubleConstantExpression.cpp b/src/ir/expressions/DoubleConstantExpression.cpp
deleted file mode 100644
index bc29cbf26..000000000
--- a/src/ir/expressions/DoubleConstantExpression.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * DoubleConstantExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include "DoubleConstantExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression<double>(double_, constantName) {
-                // Nothing to do here.
-            }
-            
-            DoubleConstantExpression::DoubleConstantExpression(DoubleConstantExpression const& doubleConstantExpression) : ConstantExpression(doubleConstantExpression) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> DoubleConstantExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new DoubleConstantExpression(*this));
-            }
-            
-            std::unique_ptr<BaseExpression> DoubleConstantExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new DoubleConstantExpression(*this));
-            }
-            
-            double DoubleConstantExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (!this->isDefined()) {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                    << "Double constant '" << this->getConstantName() << "' is undefined.";
-                } else {
-                    return this->getValue();
-                }
-            }
-            
-            void DoubleConstantExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/DoubleConstantExpression.h b/src/ir/expressions/DoubleConstantExpression.h
deleted file mode 100644
index 9eaa6eb18..000000000
--- a/src/ir/expressions/DoubleConstantExpression.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * DoubleConstantExpression.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
-
-#include "ConstantExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a constant expression of type double.
-             */
-            class DoubleConstantExpression : public ConstantExpression<double> {
-            public:
-                /*!
-                 * Creates a double constant expression with the given constant name.
-                 *
-                 * @param constantName The name of the constant to use.
-                 */
-                DoubleConstantExpression(std::string const& constantName);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param doubleConstantExpression The expression to copy.
-                 */
-                DoubleConstantExpression(DoubleConstantExpression const& doubleConstantExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ */
diff --git a/src/ir/expressions/DoubleLiteralExpression.cpp b/src/ir/expressions/DoubleLiteralExpression.cpp
deleted file mode 100644
index 08663f8f7..000000000
--- a/src/ir/expressions/DoubleLiteralExpression.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * DoubleLiteralExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "DoubleLiteralExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            DoubleLiteralExpression::DoubleLiteralExpression(double value) : BaseExpression(double_), value(value) {
-                // Nothing to do here.
-            }
-            
-            DoubleLiteralExpression::DoubleLiteralExpression(DoubleLiteralExpression const& doubleLiteralExpression)
-            : BaseExpression(doubleLiteralExpression), value(doubleLiteralExpression.value) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> DoubleLiteralExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new DoubleLiteralExpression(*this));
-            }
-
-            std::unique_ptr<BaseExpression> DoubleLiteralExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new DoubleLiteralExpression(this->value));
-            }
-            
-            double DoubleLiteralExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                return value;
-            }
-            
-            void DoubleLiteralExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string DoubleLiteralExpression::toString() const {
-                std::stringstream result;
-                result << value;
-                return result.str();
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/DoubleLiteralExpression.h b/src/ir/expressions/DoubleLiteralExpression.h
deleted file mode 100644
index 7105858c2..000000000
--- a/src/ir/expressions/DoubleLiteralExpression.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * DoubleLiteralExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
-
-#include "src/ir/expressions/BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a double literal.
-             */
-            class DoubleLiteralExpression : public BaseExpression {
-            public:
-                /*!
-                 * Creates a double literal expression with the given value.
-                 *
-                 * @param value The value for the double literal.
-                 */
-                DoubleLiteralExpression(double value);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param doubleLiteralExpression The expression to copy.
-                 */
-                DoubleLiteralExpression(DoubleLiteralExpression const& doubleLiteralExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                
-            private:
-                // The value of the double literal.
-                double value;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_ */
diff --git a/src/ir/expressions/ExpressionVisitor.h b/src/ir/expressions/ExpressionVisitor.h
deleted file mode 100644
index d301e9792..000000000
--- a/src/ir/expressions/ExpressionVisitor.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ExpressionVisitor.h
- *
- *  Created on: 26.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_
-#define STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            class BaseExpression;
-            class BinaryBooleanFunctionExpression;
-            class BinaryNumericalFunctionExpression;
-            class BinaryRelationExpression;
-            class BooleanConstantExpression;
-            class BooleanLiteralExpression;
-            class DoubleConstantExpression;
-            class DoubleLiteralExpression;
-            class IntegerConstantExpression;
-            class IntegerLiteralExpression;
-            class UnaryBooleanFunctionExpression;
-            class UnaryNumericalFunctionExpression;
-            class VariableExpression;
-            
-            class ExpressionVisitor {
-            public:
-                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(BooleanLiteralExpression* expression) = 0;
-                virtual void visit(DoubleConstantExpression* expression) = 0;
-                virtual void visit(DoubleLiteralExpression* expression) = 0;
-                virtual void visit(IntegerConstantExpression* expression) = 0;
-                virtual void visit(IntegerLiteralExpression* 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_ */
diff --git a/src/ir/expressions/Expressions.h b/src/ir/expressions/Expressions.h
deleted file mode 100644
index 634a0585d..000000000
--- a/src/ir/expressions/Expressions.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Expressions.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONS_H_
-#define STORM_IR_EXPRESSIONS_EXPRESSIONS_H_
-
-#include "BaseExpression.h"
-#include "BinaryBooleanFunctionExpression.h"
-#include "BinaryNumericalFunctionExpression.h"
-#include "BinaryRelationExpression.h"
-#include "BooleanLiteralExpression.h"
-#include "DoubleLiteralExpression.h"
-#include "IntegerLiteralExpression.h"
-#include "UnaryBooleanFunctionExpression.h"
-#include "UnaryNumericalFunctionExpression.h"
-#include "VariableExpression.h"
-#include "ConstantExpression.h"
-#include "BooleanConstantExpression.h"
-#include "IntegerConstantExpression.h"
-#include "DoubleConstantExpression.h"
-
-#endif /* STORM_IR_EXPRESSIONS_EXPRESSIONS_H_ */
diff --git a/src/ir/expressions/IntegerConstantExpression.cpp b/src/ir/expressions/IntegerConstantExpression.cpp
deleted file mode 100644
index bcc5cb0eb..000000000
--- a/src/ir/expressions/IntegerConstantExpression.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * IntegerConstantExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include "IntegerConstantExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(int_, constantName) {
-                // Nothing to do here.
-            }
-            
-            IntegerConstantExpression::IntegerConstantExpression(IntegerConstantExpression const& integerConstantExpression) : ConstantExpression(integerConstantExpression) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> IntegerConstantExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new IntegerConstantExpression(*this));
-            }
-            
-            std::unique_ptr<BaseExpression> IntegerConstantExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new IntegerConstantExpression(*this));
-            }
-            
-            double IntegerConstantExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                return static_cast<double>(getValueAsInt(variableValues));
-            }
-            
-            int_fast64_t IntegerConstantExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (!this->isDefined()) {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                    << "Integer constant '" << this->getConstantName() << "' is undefined.";
-                } else {
-                    return this->getValue();
-                }
-            }
-            
-            void IntegerConstantExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/IntegerConstantExpression.h b/src/ir/expressions/IntegerConstantExpression.h
deleted file mode 100644
index 04370574d..000000000
--- a/src/ir/expressions/IntegerConstantExpression.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * IntegerConstantExpression.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
-
-#include "ConstantExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a constant expression of type integer.
-             */
-            class IntegerConstantExpression : public ConstantExpression<int_fast64_t> {
-            public:
-                /*!
-                 * Creates an integer constant expression with the given constant name.
-                 *
-                 * @param constantName The name of the constant to use.
-                 */
-                IntegerConstantExpression(std::string const& constantName);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param integerConstantExpression The expression to copy.
-                 */
-                IntegerConstantExpression(IntegerConstantExpression const& integerConstantExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ */
diff --git a/src/ir/expressions/IntegerLiteralExpression.cpp b/src/ir/expressions/IntegerLiteralExpression.cpp
deleted file mode 100644
index ed3277f18..000000000
--- a/src/ir/expressions/IntegerLiteralExpression.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * IntegerLiteralExpression.cpp
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "IntegerLiteralExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            IntegerLiteralExpression::IntegerLiteralExpression(int_fast64_t value) : BaseExpression(int_), value(value) {
-                // Nothing to do here.
-            }
-            
-            IntegerLiteralExpression::IntegerLiteralExpression(IntegerLiteralExpression const& integerLiteralExpression)
-            : BaseExpression(integerLiteralExpression), value(integerLiteralExpression.value) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> IntegerLiteralExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new IntegerLiteralExpression(*this));
-            }
-            
-            std::unique_ptr<BaseExpression> IntegerLiteralExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new IntegerLiteralExpression(this->value));
-            }
-            
-            double IntegerLiteralExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                return static_cast<double>(value);
-            }
-            
-            int_fast64_t IntegerLiteralExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                return value;
-            }
-            
-            void IntegerLiteralExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string IntegerLiteralExpression::toString() const {
-                std::stringstream result;
-                result << value;
-                return result.str();
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
\ No newline at end of file
diff --git a/src/ir/expressions/IntegerLiteralExpression.h b/src/ir/expressions/IntegerLiteralExpression.h
deleted file mode 100644
index cb1041684..000000000
--- a/src/ir/expressions/IntegerLiteralExpression.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * IntegerLiteralExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
-
-#include "src/ir/expressions/BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing an integer literal.
-             */
-            class IntegerLiteralExpression : public BaseExpression {
-            public:
-                /*!
-                 * Creates an integer literal expression with the given value.
-                 *
-                 * @param value The value for the integer literal.
-                 */
-                IntegerLiteralExpression(int_fast64_t value);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param integerLiteralExpression The expression to copy.
-                 */
-                IntegerLiteralExpression(IntegerLiteralExpression const& integerLiteralExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                
-            private:
-                // The value of the double literal.
-                int_fast64_t value;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_ */
diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.cpp b/src/ir/expressions/UnaryBooleanFunctionExpression.cpp
deleted file mode 100644
index 3b0e6ca03..000000000
--- a/src/ir/expressions/UnaryBooleanFunctionExpression.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * UnaryBooleanFunctionExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "UnaryBooleanFunctionExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& child, FunctionType functionType) : UnaryExpression(bool_, std::move(child)), functionType(functionType) {
-                // Nothing to do here.
-            }
-            
-            UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& unaryBooleanFunctionExpression) : UnaryExpression(unaryBooleanFunctionExpression), functionType(unaryBooleanFunctionExpression.functionType) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(this->getChild()->clone(), functionType));
-            }
-            
-            std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(this->getChild()->clone(renaming, variableState), this->functionType));
-            }
-            
-            UnaryBooleanFunctionExpression::FunctionType UnaryBooleanFunctionExpression::getFunctionType() const {
-                return functionType;
-            }
-            
-            bool UnaryBooleanFunctionExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                bool resultChild = this->getChild()->getValueAsBool(variableValues);
-                switch(functionType) {
-                    case NOT: return !resultChild; break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown boolean unary operator: '" << functionType << "'.";
-                }
-            }
-            
-            void UnaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string UnaryBooleanFunctionExpression::toString() const {
-                std::stringstream result;
-                result << "(";
-                switch (functionType) {
-                    case NOT: result << "!"; break;
-                }
-                result << this->getChild()->toString() << ")";
-                
-                return result.str();
-            }
-
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h
deleted file mode 100644
index a3087f5e5..000000000
--- a/src/ir/expressions/UnaryBooleanFunctionExpression.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * UnaryBooleanFunctionExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
-
-#include "UnaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a unary function expression of boolean type.
-             */
-            class UnaryBooleanFunctionExpression : public UnaryExpression {
-            public:
-                /*!
-                 * An enum type specifying the different functions applicable.
-                 */
-                enum FunctionType {NOT};
-                
-                /*!
-                 * Creates a unary boolean function expression tree node with the given child and function type.
-                 *
-                 * @param child The child of the node.
-                 * @param functionType The operator that is to be applied to the two children.
-                 */
-                UnaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& child, FunctionType functionType);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param unaryBooleanFunctionExpression The expression to copy.
-                 */
-                UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& unaryBooleanFunctionExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-
-                /*!
-                 * Retrieves the operator that is associated with this node.
-                 *
-                 * @param The operator that is associated with this node.
-                 */
-                FunctionType getFunctionType() const;
-                
-                virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                                
-            private:
-                // The operator that is associated with this node.
-                FunctionType functionType;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/UnaryExpression.cpp b/src/ir/expressions/UnaryExpression.cpp
deleted file mode 100644
index 31463aff3..000000000
--- a/src/ir/expressions/UnaryExpression.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * UnaryExpression.cpp
- *
- *  Created on: 27.01.2013
- *      Author: Christian Dehnert
- */
-
-#include "UnaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-    
-            UnaryExpression::UnaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child) : BaseExpression(type), child(std::move(child)) {
-                // Nothing to do here.
-            }
-            
-            UnaryExpression::UnaryExpression(UnaryExpression const& unaryExpression) : BaseExpression(unaryExpression), child(unaryExpression.child->clone()) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> const& UnaryExpression::getChild() const {
-                return child;
-            }
-            
-            BaseExpression* UnaryExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
-                BaseExpression* newChild = child->performSubstitution(substitution);
-                
-                // Only update the child if it changed, because otherwise the child gets destroyed.
-                if (newChild != child.get()) {
-                    child = std::unique_ptr<BaseExpression>(newChild);
-                }
-                
-                return this;
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/expressions/UnaryExpression.h b/src/ir/expressions/UnaryExpression.h
deleted file mode 100644
index cfc685455..000000000
--- a/src/ir/expressions/UnaryExpression.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * UnaryExpression.h
- *
- *  Created on: 27.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_
-
-#include "BaseExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a generic unary expression.
-             */
-            class UnaryExpression : public BaseExpression {
-            public:
-                /*!
-                 * Constructs a unary expression with the given type and child.
-                 * @param type The type of the unary expression.
-                 * @param right The child of the unary expression.
-                 */
-                UnaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param unaryExpression The expression to copy.
-                 */
-                UnaryExpression(UnaryExpression const& unaryExpression);
-                
-                /*!
-                 * Retrieves the child of the expression node.
-                 *
-                 * @return The child of the expression node.
-                 */
-                std::unique_ptr<BaseExpression> const& getChild() const;
-
-            protected:
-                virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) override;
-                
-            private:
-                // The left child of the unary expression.
-                std::unique_ptr<BaseExpression> child;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_ */
diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.cpp b/src/ir/expressions/UnaryNumericalFunctionExpression.cpp
deleted file mode 100644
index 6b4b1fbb2..000000000
--- a/src/ir/expressions/UnaryNumericalFunctionExpression.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * UnaryFunctionExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <cmath>
-
-#include "UnaryNumericalFunctionExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child, FunctionType functionType) : UnaryExpression(type, std::move(child)), functionType(functionType) {
-                // Nothing to do here.
-            }
-            
-            UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& unaryNumericalFunctionExpression) : UnaryExpression(unaryNumericalFunctionExpression), functionType(unaryNumericalFunctionExpression.functionType) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getType(), this->getChild()->clone(), functionType));
-            }
-            
-            std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getType(), this->getChild()->clone(renaming, variableState), this->functionType));
-            }
-            
-            int_fast64_t UnaryNumericalFunctionExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != int_) {
-                    BaseExpression::getValueAsInt(variableValues);
-                }
-                
-                int_fast64_t resultChild = this->getChild()->getValueAsInt(variableValues);
-                switch(functionType) {
-                    case MINUS: return -resultChild; break;
-                    case FLOOR: return static_cast<int_fast64_t>(std::floor(resultChild)); break;
-                    case CEIL: return static_cast<int_fast64_t>(std::ceil(resultChild)); break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown numerical unary operator: '" << functionType << "'.";
-                }
-            }
-            
-            double UnaryNumericalFunctionExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != double_ && this->getType() != int_) {
-                    BaseExpression::getValueAsDouble(variableValues);
-                }
-                
-                double resultChild = this->getChild()->getValueAsDouble(variableValues);
-                switch(functionType) {
-                    case MINUS: return -resultChild; break;
-                    case FLOOR: return std::floor(resultChild); break;
-                    case CEIL: return std::ceil(resultChild); break;
-                    default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
-                        << "Unknown numerical unary operator: '" << functionType << "'.";
-                }
-            }
-            
-            UnaryNumericalFunctionExpression::FunctionType UnaryNumericalFunctionExpression::getFunctionType() const {
-                return functionType;
-            }
-            
-            void UnaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string UnaryNumericalFunctionExpression::toString() const {
-                std::stringstream result;
-                result << "(";
-                switch (functionType) {
-                    case MINUS: result << "-"; break;
-                    case FLOOR: result << "floor("; break;
-                    case CEIL: result << "ceil("; break;
-                }
-                result << this->getChild()->toString() << ")";
-                
-                return result.str();
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h
deleted file mode 100644
index bcb942378..000000000
--- a/src/ir/expressions/UnaryNumericalFunctionExpression.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * UnaryFunctionExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_UNARYFUNCTIONEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_UNARYFUNCTIONEXPRESSION_H_
-
-#include "UnaryExpression.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            /*!
-             * A class representing a unary function expression of numerical type.
-             */
-            class UnaryNumericalFunctionExpression : public UnaryExpression {
-            public:
-                /*!
-                 * An enum type specifying the different functions applicable.
-                 */
-                enum FunctionType {MINUS, FLOOR, CEIL};
-                
-                /*!
-                 * Creates a unary numerical function expression tree node with the given child and function type.
-                 *
-                 * @param child The child of the node.
-                 * @param functionType The operator that is to be applied to the two children.
-                 */
-                UnaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child, FunctionType functionType);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param unaryNumericalFunctionExpression The expression to copy.
-                 */
-                UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& unaryNumericalFunctionExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-                virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-                
-                virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-                
-                /*!
-                 * Retrieves the operator that is associated with this node.
-                 *
-                 * @param The operator that is associated with this node.
-                 */
-                FunctionType getFunctionType() const;
-                
-                virtual void accept(ExpressionVisitor* visitor) override;
-                
-                virtual std::string toString() const override;
-                
-            private:
-                // The operator that is associated with this node.
-                FunctionType functionType;
-            };
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_UNARYFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/VariableExpression.cpp b/src/ir/expressions/VariableExpression.cpp
deleted file mode 100644
index 9bf09a734..000000000
--- a/src/ir/expressions/VariableExpression.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * VariableExpression.cpp
- *
- *  Created on: 10.06.2013
- *      Author: Christian Dehnert
- */
-
-#include "VariableExpression.h"
-#include "src/parser/prismparser/VariableState.h"
-#include "src/exceptions/ExpressionEvaluationException.h"
-
-namespace storm {
-    namespace ir {
-        namespace expressions {
-            
-            VariableExpression::VariableExpression(ReturnType type, std::string const& variableName) : BaseExpression(type), globalIndex(0), variableName(variableName) {
-                // Nothing to do here.
-            }
-            
-            VariableExpression::VariableExpression(ReturnType type, uint_fast64_t globalIndex, std::string const& variableName)
-            : BaseExpression(type), globalIndex(globalIndex), variableName(variableName) {
-                // Nothing to do here.
-            }
-            
-            VariableExpression::VariableExpression(VariableExpression const& variableExpression) : BaseExpression(variableExpression), globalIndex(variableExpression.globalIndex), variableName(variableExpression.variableName) {
-                // Nothing to do here.
-            }
-            
-            std::unique_ptr<BaseExpression> VariableExpression::clone() const {
-                return std::unique_ptr<BaseExpression>(new VariableExpression(*this));
-            }
-            
-            std::unique_ptr<BaseExpression> VariableExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
-                // Perform the proper cloning.
-                auto renamingPair = renaming.find(this->variableName);
-                if (renamingPair != renaming.end()) {
-                    if (this->getType() == int_) {
-                        return variableState.getIntegerVariableExpression(renamingPair->second)->clone();
-                    } else {
-                        return variableState.getBooleanVariableExpression(renamingPair->second)->clone();
-                    }
-                } else {
-                    if (this->getType() == int_) {
-                        return variableState.getIntegerVariableExpression(this->variableName)->clone();
-                    } else {
-                        return variableState.getBooleanVariableExpression(this->variableName)->clone();
-                    }
-                }
-            }
-            
-            BaseExpression* VariableExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
-                // If the name of the variable is a key of the map, we need to replace it.
-                auto substitutionIterator = substitution.find(variableName);
-                
-                if (substitutionIterator != substitution.end()) {
-                    std::unique_ptr<BaseExpression> expressionClone = substitutionIterator->second.get().clone();
-                    BaseExpression* rawPointer = expressionClone.release();
-                    return rawPointer;
-                } else {
-                    // Otherwise, we don't need to replace anything.
-                    return this;
-                }
-            }
-            
-            void VariableExpression::accept(ExpressionVisitor* visitor) {
-                visitor->visit(this);
-            }
-            
-            std::string VariableExpression::toString() const {
-                return this->variableName;
-            }
-            
-            int_fast64_t VariableExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != int_) {
-                    BaseExpression::getValueAsInt(variableValues);
-                }
-                
-                if (variableValues != nullptr) {
-                    return variableValues->second[globalIndex];
-                } else {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression involving variables without variable values.";
-                }
-            }
-            
-            bool VariableExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != bool_) {
-                    BaseExpression::getValueAsBool(variableValues);
-                }
-                
-                if (variableValues != nullptr) {
-                    return variableValues->first[globalIndex];
-                } else {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression involving variables without variable values.";
-                }
-            }
-            
-            double VariableExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
-                if (this->getType() != double_ && this->getType() != int_) {
-                    BaseExpression::getValueAsDouble(variableValues);
-                }
-                
-                // Because only int variables can deliver a double value, we only need to check them.
-                if (variableValues != nullptr) {
-                    return static_cast<double>(variableValues->second[globalIndex]);
-                } else {
-                    throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression with variable '" << variableName << "' of type double.";
-                }
-            }
-            
-            std::string const& VariableExpression::getVariableName() const {
-                return variableName;
-            }
-            
-            uint_fast64_t VariableExpression::getGlobalVariableIndex() const {
-                return this->globalIndex;
-            }
-            
-        } // namespace expressions
-    } // namespace ir
-} // namespace storm
diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h
deleted file mode 100644
index 99358d377..000000000
--- a/src/ir/expressions/VariableExpression.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * VariableExpression.h
- *
- *  Created on: 03.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_EXPRESSIONS_VARIABLEEXPRESSION_H_
-#define STORM_IR_EXPRESSIONS_VARIABLEEXPRESSION_H_
-
-#include "BaseExpression.h"
-
-namespace storm {
-	
-    // Forward-declare VariableState.
-	namespace parser {
-		namespace prismparser {
-			class VariableState;
-		} // namespace prismparser
-	} // namespace parser
-    
-	namespace ir {
-		namespace expressions {
-			
-            /*!
-             * A class representing a variable in the expression tree.
-             */
-			class VariableExpression : public BaseExpression {
-			public:
-                /*!
-                 * Creates a variable expression of the given type with the given name. As this variable has no indices
-                 * it is only meant as a dummy and needs to be replaced with a "full" variable expression.
-                 *
-                 * @param type The type of the variable.
-                 * @param variableName The name of the variable.
-                 */
-				VariableExpression(ReturnType type, std::string const& variableName);
-				
-                /*!
-                 * Creates a variable expression of the given type with the given name and indices.
-                 *
-                 * @param type The type of the variable.
-                 * @param globalIndex The global (i.e. program-wide) index of the variable.
-                 * @param variableName The name of the variable.
-                 */
-				VariableExpression(ReturnType type, uint_fast64_t globalIndex, std::string const& variableName);
-                
-                /*!
-                 * Copy-constructs from the given expression.
-                 *
-                 * @param variableExpression The expression to copy.
-                 */
-                VariableExpression(VariableExpression const& variableExpression);
-                
-                virtual std::unique_ptr<BaseExpression> clone() const override;
-                
-				virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
-				            
-				virtual void accept(ExpressionVisitor* visitor) override;
-				
-				virtual std::string toString() const override;
-				
-				virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-				
-				virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-				
-				virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
-				
-                /*!
-                 * Retrieves the name of the variable.
-                 *
-                 * @return The name of the variable.
-                 */
-				std::string const& getVariableName() const;
-				
-                /*!
-                 * Retrieves the global (i.e. program-wide) index of the variable.
-                 *
-                 * @return The global index of the variable.
-                 */
-				uint_fast64_t getGlobalVariableIndex() const;
-				            
-            protected:
-                virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) override;
-                
-			private:
-                // The global index of the variable.
-				uint_fast64_t globalIndex;
-                
-                // The name of the variable.
-				std::string variableName;
-			};
-			
-		} // namespace expressions
-	} // namespace ir
-} // namespace storm
-
-#endif /* STORM_IR_EXPRESSIONS_VARIABLEEXPRESSION_H_ */
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 97ca50507..69fadf5c9 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -7,25 +7,25 @@
 
 namespace storm {
     namespace dd {
-        Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
+        Dd<DdType::CUDD>::Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
             // Intentionally left empty.
         }
         
-        bool Dd<CUDD>::operator==(Dd<CUDD> const& other) const {
+        bool Dd<DdType::CUDD>::operator==(Dd<DdType::CUDD> const& other) const {
             return this->cuddAdd == other.getCuddAdd();
         }
         
-        bool Dd<CUDD>::operator!=(Dd<CUDD> const& other) const {
+        bool Dd<DdType::CUDD>::operator!=(Dd<DdType::CUDD> const& other) const {
             return this->cuddAdd == other.getCuddAdd();
         }
         
-        Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator+(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result += other;
             return result;
         }
         
-        Dd<CUDD>& Dd<CUDD>::operator+=(Dd<CUDD> const& other) {
+        Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator+=(Dd<DdType::CUDD> const& other) {
             this->cuddAdd += other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
@@ -34,13 +34,13 @@ namespace storm {
             return *this;
         }
         
-        Dd<CUDD> Dd<CUDD>::operator*(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator*(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result *= other;
             return result;
         }
         
-        Dd<CUDD>& Dd<CUDD>::operator*=(Dd<CUDD> const& other) {
+        Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator*=(Dd<DdType::CUDD> const& other) {
             this->cuddAdd *= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
@@ -49,13 +49,13 @@ namespace storm {
             return *this;
         }
         
-        Dd<CUDD> Dd<CUDD>::operator-(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator-(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result -= other;
             return result;
         }
         
-        Dd<CUDD>& Dd<CUDD>::operator-=(Dd<CUDD> const& other) {
+        Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator-=(Dd<DdType::CUDD> const& other) {
             this->cuddAdd -= other.getCuddAdd();
             
             // Join the variable sets of the two participating DDs.
@@ -64,13 +64,13 @@ namespace storm {
             return *this;
         }
         
-        Dd<CUDD> Dd<CUDD>::operator/(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator/(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result /= other;
             return result;
         }
         
-        Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
+        Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator/=(Dd<DdType::CUDD> const& other) {
             this->cuddAdd = this->cuddAdd.Divide(other.getCuddAdd());
             
             // Join the variable sets of the two participating DDs.
@@ -79,55 +79,55 @@ namespace storm {
             return *this;
         }
         
-        Dd<CUDD> Dd<CUDD>::operator~() const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator~() const {
+            Dd<DdType::CUDD> result(*this);
             result.complement();
             return result;
         }
         
-        Dd<CUDD>& Dd<CUDD>::complement() {
+        Dd<DdType::CUDD>& Dd<DdType::CUDD>::complement() {
             this->cuddAdd = ~this->cuddAdd;
             return *this;
         }
         
-        Dd<CUDD> Dd<CUDD>::equals(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::equals(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result.cuddAdd = result.cuddAdd.Equals(other.getCuddAdd());
             return result;
         }
         
-        Dd<CUDD> Dd<CUDD>::notEquals(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::notEquals(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result.cuddAdd = result.cuddAdd.NotEquals(other.getCuddAdd());
             return result;
         }
         
-        Dd<CUDD> Dd<CUDD>::less(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::less(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result.cuddAdd = result.cuddAdd.LessThan(other.getCuddAdd());
             return result;
         }
         
-        Dd<CUDD> Dd<CUDD>::lessOrEqual(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::lessOrEqual(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result.cuddAdd = result.cuddAdd.LessThanOrEqual(other.getCuddAdd());
             return result;
         }
         
-        Dd<CUDD> Dd<CUDD>::greater(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::greater(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result.cuddAdd = result.cuddAdd.GreaterThan(other.getCuddAdd());
             return result;
         }
         
-        Dd<CUDD> Dd<CUDD>::greaterOrEqual(Dd<CUDD> const& other) const {
-            Dd<CUDD> result(*this);
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::greaterOrEqual(Dd<DdType::CUDD> const& other) const {
+            Dd<DdType::CUDD> result(*this);
             result.cuddAdd = result.cuddAdd.GreaterThanOrEqual(other.getCuddAdd());
             return result;
         }
         
-        void Dd<CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
-            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+        void Dd<DdType::CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
+            Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
@@ -136,15 +136,15 @@ namespace storm {
                 }
                 this->getContainedMetaVariableNames().erase(metaVariableName);
                 
-                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
             this->cuddAdd = this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
-            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+        void Dd<DdType::CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
+            Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
@@ -153,15 +153,15 @@ namespace storm {
                 }
                 this->getContainedMetaVariableNames().erase(metaVariableName);
                 
-                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
             this->cuddAdd = this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
-            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+        void Dd<DdType::CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
+            Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
@@ -170,15 +170,15 @@ namespace storm {
                 }
                 this->getContainedMetaVariableNames().erase(metaVariableName);
                 
-                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
             this->cuddAdd = this->cuddAdd.MinAbstract(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
-            Dd<CUDD> cubeDd(this->getDdManager()->getOne());
+        void Dd<DdType::CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
+            Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
@@ -187,19 +187,19 @@ namespace storm {
                 }
                 this->getContainedMetaVariableNames().erase(metaVariableName);
                 
-                DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
             this->cuddAdd = this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd());
         }
         
-        void Dd<CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
+        void Dd<DdType::CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
             std::vector<ADD> from;
             std::vector<ADD> to;
             for (auto const& metaVariablePair : metaVariablePairs) {
-                DdMetaVariable<CUDD> const& variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first);
-                DdMetaVariable<CUDD> const& variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second);
+                DdMetaVariable<DdType::CUDD> const& variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first);
+                DdMetaVariable<DdType::CUDD> const& variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second);
 
                 // Check if it's legal so swap the meta variables.
                 if (variable1.getNumberOfDdVariables() != variable2.getNumberOfDdVariables()) {
@@ -230,7 +230,7 @@ namespace storm {
             this->cuddAdd = this->cuddAdd.SwapVariables(from, to);
         }
         
-        Dd<CUDD> Dd<CUDD>::multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
             std::vector<ADD> summationDdVariables;
             
             // Create the CUDD summation variables.
@@ -245,10 +245,10 @@ namespace storm {
             std::set<std::string> containedMetaVariableNames;
             std::set_difference(unionOfMetaVariableNames.begin(), unionOfMetaVariableNames.end(), summationMetaVariableNames.begin(), summationMetaVariableNames.end(), std::inserter(containedMetaVariableNames, containedMetaVariableNames.begin()));
             
-            return Dd<CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
+            return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
         }
         
-        uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
+        uint_fast64_t Dd<DdType::CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
             for (auto const& metaVariableName : this->containedMetaVariableNames) {
                 numberOfDdVariables += this->getDdManager()->getMetaVariable(metaVariableName).getNumberOfDdVariables();
@@ -256,39 +256,39 @@ namespace storm {
             return static_cast<uint_fast64_t>(this->cuddAdd.CountMinterm(static_cast<int>(numberOfDdVariables)));
         }
         
-        uint_fast64_t Dd<CUDD>::getLeafCount() const {
+        uint_fast64_t Dd<DdType::CUDD>::getLeafCount() const {
             return static_cast<uint_fast64_t>(this->cuddAdd.CountLeaves());
         }
         
-        uint_fast64_t Dd<CUDD>::getNodeCount() const {
+        uint_fast64_t Dd<DdType::CUDD>::getNodeCount() const {
             return static_cast<uint_fast64_t>(this->cuddAdd.nodeCount());
         }
         
-        double Dd<CUDD>::getMin() const {
+        double Dd<DdType::CUDD>::getMin() const {
             ADD constantMinAdd = this->cuddAdd.FindMin();
             return static_cast<double>(Cudd_V(constantMinAdd.getNode()));
         }
         
-        double Dd<CUDD>::getMax() const {
+        double Dd<DdType::CUDD>::getMax() const {
             ADD constantMaxAdd = this->cuddAdd.FindMax();
             return static_cast<double>(Cudd_V(constantMaxAdd.getNode()));
         }
         
-        void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
+        void Dd<DdType::CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
             std::map<std::string, int_fast64_t> metaVariableNameToValueMap;
             metaVariableNameToValueMap.emplace(metaVariableName, variableValue);
             this->setValue(metaVariableNameToValueMap, targetValue);
         }
         
-        void Dd<CUDD>::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) {
+        void Dd<DdType::CUDD>::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) {
             std::map<std::string, int_fast64_t> metaVariableNameToValueMap;
             metaVariableNameToValueMap.emplace(metaVariableName1, variableValue1);
             metaVariableNameToValueMap.emplace(metaVariableName2, variableValue2);
             this->setValue(metaVariableNameToValueMap, targetValue);
         }
         
-        void Dd<CUDD>::setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
-            Dd<CUDD> valueEncoding(this->getDdManager()->getOne());
+        void Dd<DdType::CUDD>::setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
+            Dd<DdType::CUDD> valueEncoding(this->getDdManager()->getOne());
             for (auto const& nameValuePair : metaVariableNameToValueMap) {
                 valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
                 // Also record that the DD now contains the meta variable.
@@ -298,9 +298,9 @@ namespace storm {
             this->cuddAdd = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
         }
         
-        double Dd<CUDD>::getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const {
+        double Dd<DdType::CUDD>::getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const {
             std::set<std::string> remainingMetaVariables(this->getContainedMetaVariableNames());
-            Dd<CUDD> valueEncoding(this->getDdManager()->getOne());
+            Dd<DdType::CUDD> valueEncoding(this->getDdManager()->getOne());
             for (auto const& nameValuePair : metaVariableNameToValueMap) {
                 valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
                 if (this->containsMetaVariable(nameValuePair.first)) {
@@ -312,29 +312,29 @@ namespace storm {
                 throw storm::exceptions::InvalidArgumentException() << "Cannot evaluate function for which not all inputs were given.";
             }
             
-            Dd<CUDD> value = *this * valueEncoding;
+            Dd<DdType::CUDD> value = *this * valueEncoding;
             value.sumAbstract(this->getContainedMetaVariableNames());
             return static_cast<double>(Cudd_V(value.getCuddAdd().getNode()));
         }
         
-        bool Dd<CUDD>::isOne() const {
+        bool Dd<DdType::CUDD>::isOne() const {
             return *this == this->getDdManager()->getOne();
         }
         
-        bool Dd<CUDD>::isZero() const {
+        bool Dd<DdType::CUDD>::isZero() const {
             return *this == this->getDdManager()->getZero();
         }
         
-        bool Dd<CUDD>::isConstant() const {
+        bool Dd<DdType::CUDD>::isConstant() const {
             return Cudd_IsConstant(this->cuddAdd.getNode());
         }
         
-        bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
+        bool Dd<DdType::CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
             auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
             return metaVariable != containedMetaVariableNames.end();
         }
         
-        bool Dd<CUDD>::containsMetaVariables(std::set<std::string> metaVariableNames) const {
+        bool Dd<DdType::CUDD>::containsMetaVariables(std::set<std::string> metaVariableNames) const {
             for (auto const& metaVariableName : metaVariableNames) {
                 auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
                 
@@ -345,15 +345,15 @@ namespace storm {
             return true;
         }
         
-        std::set<std::string> const& Dd<CUDD>::getContainedMetaVariableNames() const {
+        std::set<std::string> const& Dd<DdType::CUDD>::getContainedMetaVariableNames() const {
             return this->containedMetaVariableNames;
         }
         
-        std::set<std::string>& Dd<CUDD>::getContainedMetaVariableNames() {
+        std::set<std::string>& Dd<DdType::CUDD>::getContainedMetaVariableNames() {
             return this->containedMetaVariableNames;
         }
         
-        void Dd<CUDD>::exportToDot(std::string const& filename) const {
+        void Dd<DdType::CUDD>::exportToDot(std::string const& filename) const {
 			std::vector<ADD> cuddAddVector = { this->cuddAdd };
 			if (filename.empty()) {
 				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector);
@@ -364,27 +364,27 @@ namespace storm {
             }
         }
         
-        ADD Dd<CUDD>::getCuddAdd() {
+        ADD Dd<DdType::CUDD>::getCuddAdd() {
             return this->cuddAdd;
         }
         
-        ADD const& Dd<CUDD>::getCuddAdd() const {
+        ADD const& Dd<DdType::CUDD>::getCuddAdd() const {
             return this->cuddAdd;
         }
         
-        void Dd<CUDD>::addContainedMetaVariable(std::string const& metaVariableName) {
+        void Dd<DdType::CUDD>::addContainedMetaVariable(std::string const& metaVariableName) {
             this->getContainedMetaVariableNames().insert(metaVariableName);
         }
 
-        void Dd<CUDD>::removeContainedMetaVariable(std::string const& metaVariableName) {
+        void Dd<DdType::CUDD>::removeContainedMetaVariable(std::string const& metaVariableName) {
             this->getContainedMetaVariableNames().erase(metaVariableName);
         }
         
-        std::shared_ptr<DdManager<CUDD>> Dd<CUDD>::getDdManager() const {
+        std::shared_ptr<DdManager<DdType::CUDD>> Dd<DdType::CUDD>::getDdManager() const {
             return this->ddManager;
         }
         
-        std::ostream & operator<<(std::ostream& out, const Dd<CUDD>& dd) {
+        std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
             dd.exportToDot();
             return out;
         }
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 80cf88f3a..6da2dc9c3 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -18,18 +18,18 @@ namespace storm {
         template<DdType Type> class DdManager;
         
         template<>
-        class Dd<CUDD> {
+        class Dd<DdType::CUDD> {
         public:
             // Declare the DdManager class as friend so it can access the internals of a DD.
-            friend class DdManager<CUDD>;
+            friend class DdManager<DdType::CUDD>;
             
             // Instantiate all copy/move constructors/assignments with the default implementation.
             Dd() = default;
-            Dd(Dd<CUDD> const& other) = default;
-			Dd& operator=(Dd<CUDD> const& other) = default;
+            Dd(Dd<DdType::CUDD> const& other) = default;
+			Dd& operator=(Dd<DdType::CUDD> const& other) = default;
 #ifndef WINDOWS
-            Dd(Dd<CUDD>&& other) = default;
-            Dd& operator=(Dd<CUDD>&& other) = default;
+            Dd(Dd<DdType::CUDD>&& other) = default;
+            Dd& operator=(Dd<DdType::CUDD>&& other) = default;
 #endif
             
             /*!
@@ -38,7 +38,7 @@ namespace storm {
              * @param other The DD that is to be compared with the current one.
              * @return True if the DDs represent the same function.
              */
-            bool operator==(Dd<CUDD> const& other) const;
+            bool operator==(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Retrieves whether the two DDs represent different functions.
@@ -46,7 +46,7 @@ namespace storm {
              * @param other The DD that is to be compared with the current one.
              * @return True if the DDs represent the different functions.
              */
-            bool operator!=(Dd<CUDD> const& other) const;
+            bool operator!=(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Adds the two DDs.
@@ -54,7 +54,7 @@ namespace storm {
              * @param other The DD to add to the current one.
              * @return The result of the addition.
              */
-            Dd<CUDD> operator+(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> operator+(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Adds the given DD to the current one.
@@ -62,7 +62,7 @@ namespace storm {
              * @param other The DD to add to the current one.
              * @return A reference to the current DD after the operation.
              */
-            Dd<CUDD>& operator+=(Dd<CUDD> const& other);
+            Dd<DdType::CUDD>& operator+=(Dd<DdType::CUDD> const& other);
             
             /*!
              * Multiplies the two DDs.
@@ -70,7 +70,7 @@ namespace storm {
              * @param other The DD to multiply with the current one.
              * @return The result of the multiplication.
              */
-            Dd<CUDD> operator*(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> operator*(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Multiplies the given DD with the current one and assigns the result to the current DD.
@@ -78,7 +78,7 @@ namespace storm {
              * @param other The DD to multiply with the current one.
              * @return A reference to the current DD after the operation.
              */
-            Dd<CUDD>& operator*=(Dd<CUDD> const& other);
+            Dd<DdType::CUDD>& operator*=(Dd<DdType::CUDD> const& other);
             
             /*!
              * Subtracts the given DD from the current one.
@@ -86,7 +86,7 @@ namespace storm {
              * @param other The DD to subtract from the current one.
              * @return The result of the subtraction.
              */
-            Dd<CUDD> operator-(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> operator-(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Subtracts the given DD from the current one and assigns the result to the current DD.
@@ -94,7 +94,7 @@ namespace storm {
              * @param other The DD to subtract from the current one.
              * @return A reference to the current DD after the operation.
              */
-            Dd<CUDD>& operator-=(Dd<CUDD> const& other);
+            Dd<DdType::CUDD>& operator-=(Dd<DdType::CUDD> const& other);
             
             /*!
              * Divides the current DD by the given one.
@@ -102,7 +102,7 @@ namespace storm {
              * @param other The DD by which to divide the current one.
              * @return The result of the division.
              */
-            Dd<CUDD> operator/(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> operator/(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Divides the current DD by the given one and assigns the result to the current DD.
@@ -110,14 +110,14 @@ namespace storm {
              * @param other The DD by which to divide the current one.
              * @return A reference to the current DD after the operation.
              */
-            Dd<CUDD>& operator/=(Dd<CUDD> const& other);
+            Dd<DdType::CUDD>& operator/=(Dd<DdType::CUDD> const& other);
             
             /*!
              * Subtracts the DD from the constant zero function.
              *
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> minus() const;
+            Dd<DdType::CUDD> minus() const;
             
             /*!
              * Retrieves the logical complement of the current DD. The result will map all encodings with a value
@@ -125,7 +125,7 @@ namespace storm {
              *
              * @return The logical complement of the current DD.
              */
-            Dd<CUDD> operator~() const;
+            Dd<DdType::CUDD> operator~() const;
             
             /*!
              * Logically complements the current DD. The result will map all encodings with a value
@@ -133,7 +133,7 @@ namespace storm {
              *
              * @return A reference to the current DD after the operation.
              */
-            Dd<CUDD>& complement();
+            Dd<DdType::CUDD>& complement();
             
             /*!
              * Retrieves the function that maps all evaluations to one that have an identical function values.
@@ -141,7 +141,7 @@ namespace storm {
              * @param other The DD with which to perform the operation.
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> equals(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> equals(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Retrieves the function that maps all evaluations to one that have distinct function values.
@@ -149,7 +149,7 @@ namespace storm {
              * @param other The DD with which to perform the operation.
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> notEquals(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> notEquals(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Retrieves the function that maps all evaluations to one whose function value in the first DD are less
@@ -158,7 +158,7 @@ namespace storm {
              * @param other The DD with which to perform the operation.
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> less(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> less(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Retrieves the function that maps all evaluations to one whose function value in the first DD are less or
@@ -167,7 +167,7 @@ namespace storm {
              * @param other The DD with which to perform the operation.
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> lessOrEqual(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> lessOrEqual(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
@@ -176,7 +176,7 @@ namespace storm {
              * @param other The DD with which to perform the operation.
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> greater(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> greater(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
@@ -185,7 +185,7 @@ namespace storm {
              * @param other The DD with which to perform the operation.
              * @return The resulting function represented as a DD.
              */
-            Dd<CUDD> greaterOrEqual(Dd<CUDD> const& other) const;
+            Dd<DdType::CUDD> greaterOrEqual(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Existentially abstracts from the given meta variables.
@@ -232,7 +232,7 @@ namespace storm {
              * matrix multiplication.
              * @return A DD representing the result of the matrix-matrix multiplication.
              */
-            Dd<CUDD> multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames);
+            Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames);
             
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.
@@ -378,9 +378,9 @@ namespace storm {
              *
              * A pointer to the manager that is responsible for this DD.
              */
-            std::shared_ptr<DdManager<CUDD>> getDdManager() const;
+            std::shared_ptr<DdManager<DdType::CUDD>> getDdManager() const;
             
-            friend std::ostream & operator<<(std::ostream& out, const Dd<CUDD>& dd);
+            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.
@@ -417,10 +417,10 @@ namespace storm {
              * @param cuddAdd The CUDD ADD to store.
              * @param
              */
-            Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
+            Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
             
             // A pointer to the manager responsible for this DD.
-            std::shared_ptr<DdManager<CUDD>> ddManager;
+            std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
             
             // The ADD created by CUDD.
             ADD cuddAdd;
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 3c87157b2..9843b5c92 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -6,29 +6,29 @@
 
 namespace storm {
     namespace dd {
-        DdManager<CUDD>::DdManager() : metaVariableMap(), cuddManager() {
+        DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
             // Intentionally left empty.
         }
         
-        Dd<CUDD> DdManager<CUDD>::getOne() {
-            return Dd<CUDD>(this->shared_from_this(), cuddManager.addOne());
+        Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() {
+            return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addOne());
         }
         
-        Dd<CUDD> DdManager<CUDD>::getZero() {
-            return Dd<CUDD>(this->shared_from_this(), cuddManager.addZero());
+        Dd<DdType::CUDD> DdManager<DdType::CUDD>::getZero() {
+            return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addZero());
         }
         
-        Dd<CUDD> DdManager<CUDD>::getConstant(double value) {
-            return Dd<CUDD>(this->shared_from_this(), cuddManager.constant(value));
+        Dd<DdType::CUDD> DdManager<DdType::CUDD>::getConstant(double value) {
+            return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.constant(value));
         }
         
-        Dd<CUDD> DdManager<CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
+        Dd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
             // Check whether the meta variable exists.
             if (!this->hasMetaVariable(metaVariableName)) {
                 throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
             }
             
-            DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
+            DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
             // Check whether the value is legal for this meta variable.
             if (value < metaVariable.getLow() || value > metaVariable.getHigh()) {
@@ -38,9 +38,9 @@ namespace storm {
             // Now compute the encoding relative to the low value of the meta variable.
             value -= metaVariable.getLow();
             
-            std::vector<Dd<CUDD>> const& ddVariables = metaVariable.getDdVariables();
+            std::vector<Dd<DdType::CUDD>> const& ddVariables = metaVariable.getDdVariables();
 
-            Dd<CUDD> result;
+            Dd<DdType::CUDD> result;
             if (value & (1ull << (ddVariables.size() - 1))) {
                 result = ddVariables[0];
             } else {
@@ -58,15 +58,15 @@ namespace storm {
             return result;
         }
         
-        Dd<CUDD> DdManager<CUDD>::getRange(std::string const& metaVariableName) {
+        Dd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(std::string const& metaVariableName) {
             // Check whether the meta variable exists.
             if (!this->hasMetaVariable(metaVariableName)) {
                 throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
             }
 
-            storm::dd::DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
+            storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
-            Dd<CUDD> result = this->getZero();
+            Dd<DdType::CUDD> result = this->getZero();
             
             for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
                 result.setValue(metaVariableName, value, static_cast<double>(1));
@@ -74,22 +74,22 @@ namespace storm {
             return result;
         }
         
-        Dd<CUDD> DdManager<CUDD>::getIdentity(std::string const& metaVariableName) {
+        Dd<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(std::string const& metaVariableName) {
             // Check whether the meta variable exists.
             if (!this->hasMetaVariable(metaVariableName)) {
                 throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
             }
             
-            storm::dd::DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
+            storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
-            Dd<CUDD> result = this->getZero();
+            Dd<DdType::CUDD> result = this->getZero();
             for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
                 result.setValue(metaVariableName, value, static_cast<double>(value));
             }
             return result;
         }
 
-        void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
+        void DdManager<DdType::CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
             // Check whether a meta variable already exists.
             if (this->hasMetaVariable(name)) {
                 throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
@@ -102,15 +102,15 @@ namespace storm {
             
             std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
             
-            std::vector<Dd<CUDD>> variables;
+            std::vector<Dd<DdType::CUDD>> variables;
             for (std::size_t i = 0; i < numberOfBits; ++i) {
-                variables.emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
+                variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
             }
             
-            metaVariableMap.emplace(name, DdMetaVariable<CUDD>(name, low, high, variables, this->shared_from_this()));
+            metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, low, high, variables, this->shared_from_this()));
         }
         
-        void DdManager<CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
+        void DdManager<DdType::CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
             // Make sure that at least one meta variable is added.
             if (names.size() == 0) {
                 throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables.";
@@ -137,20 +137,20 @@ namespace storm {
             
             // Add the variables in interleaved order.
             std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
-            std::vector<std::vector<Dd<CUDD>>> variables(names.size());
+            std::vector<std::vector<Dd<DdType::CUDD>>> variables(names.size());
             for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
                 for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                    variables[i].emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
+                    variables[i].emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
                 }
             }
             
             // Now add the meta variables.
             for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                metaVariableMap.emplace(names[i], DdMetaVariable<CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
+                metaVariableMap.emplace(names[i], DdMetaVariable<DdType::CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
             }
         }
         
-        DdMetaVariable<CUDD> const& DdManager<CUDD>::getMetaVariable(std::string const& metaVariableName) const {
+        DdMetaVariable<DdType::CUDD> const& DdManager<DdType::CUDD>::getMetaVariable(std::string const& metaVariableName) const {
             auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
             
             if (!this->hasMetaVariable(metaVariableName)) {
@@ -160,7 +160,7 @@ namespace storm {
             return nameVariablePair->second;
         }
         
-        std::set<std::string> DdManager<CUDD>::getAllMetaVariableNames() const {
+        std::set<std::string> DdManager<DdType::CUDD>::getAllMetaVariableNames() const {
             std::set<std::string> result;
             for (auto const& nameValuePair : metaVariableMap) {
                 result.insert(nameValuePair.first);
@@ -168,15 +168,15 @@ namespace storm {
             return result;
         }
         
-        std::size_t DdManager<CUDD>::getNumberOfMetaVariables() const {
+        std::size_t DdManager<DdType::CUDD>::getNumberOfMetaVariables() const {
             return this->metaVariableMap.size();
         }
         
-        bool DdManager<CUDD>::hasMetaVariable(std::string const& metaVariableName) const {
+        bool DdManager<DdType::CUDD>::hasMetaVariable(std::string const& metaVariableName) const {
             return this->metaVariableMap.find(metaVariableName) != this->metaVariableMap.end();
         }
         
-        Cudd& DdManager<CUDD>::getCuddManager() {
+        Cudd& DdManager<DdType::CUDD>::getCuddManager() {
             return this->cuddManager;
         }
     }
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 569ccf1c9..ca3f9c2c3 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -14,10 +14,10 @@
 namespace storm {
     namespace dd {
         template<>
-        class DdManager<CUDD> : public std::enable_shared_from_this<DdManager<CUDD>> {
+        class DdManager<DdType::CUDD> : public std::enable_shared_from_this<DdManager<DdType::CUDD>> {
         public:
             // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
-            friend class Dd<CUDD>;
+            friend class Dd<DdType::CUDD>;
             
             /*!
              * Creates an empty manager without any meta variables.
@@ -25,11 +25,11 @@ namespace storm {
             DdManager();
             
             // Explictly forbid copying a DdManager, but allow moving it.
-            DdManager(DdManager<CUDD> const& other) = delete;
-			DdManager<CUDD>& operator=(DdManager<CUDD> const& other) = delete;
+            DdManager(DdManager<DdType::CUDD> const& other) = delete;
+			DdManager<DdType::CUDD>& operator=(DdManager<DdType::CUDD> const& other) = delete;
 #ifndef WINDOWS
-            DdManager(DdManager<CUDD>&& other) = default;
-            DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
+            DdManager(DdManager<DdType::CUDD>&& other) = default;
+            DdManager<DdType::CUDD>& operator=(DdManager<DdType::CUDD>&& other) = default;
 #endif
             
             /*!
@@ -37,21 +37,21 @@ namespace storm {
              *
              * @return A DD representing the constant one function.
              */
-            Dd<CUDD> getOne();
+            Dd<DdType::CUDD> getOne();
             
             /*!
              * Retrieves a DD representing the constant zero function.
              *
              * @return A DD representing the constant zero function.
              */
-            Dd<CUDD> getZero();
+            Dd<DdType::CUDD> getZero();
             
             /*!
              * Retrieves a DD representing the constant function with the given value.
              *
              * @return A DD representing the constant function with the given value.
              */
-            Dd<CUDD> getConstant(double value);
+            Dd<DdType::CUDD> getConstant(double value);
             
             /*!
              * Retrieves the DD representing the function that maps all inputs which have the given meta variable equal
@@ -62,7 +62,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<CUDD> getEncoding(std::string const& metaVariableName, int_fast64_t value);
+            Dd<DdType::CUDD> getEncoding(std::string const& metaVariableName, int_fast64_t value);
             
             /*!
              * Retrieves the DD representing the range of the meta variable, i.e., a function that maps all legal values
@@ -71,7 +71,7 @@ namespace storm {
              * @param metaVariableName The name of the meta variable whose range to retrieve.
              * @return The range of the meta variable.
              */
-            Dd<CUDD> getRange(std::string const& metaVariableName);
+            Dd<DdType::CUDD> getRange(std::string const& metaVariableName);
 
             /*!
              * Retrieves the DD representing the identity of the meta variable, i.e., a function that maps all legal
@@ -80,7 +80,7 @@ namespace storm {
              * @param metaVariableName The name of the meta variable whose identity to retrieve.
              * @return The identity of the meta variable.
              */
-            Dd<CUDD> getIdentity(std::string const& metaVariableName);
+            Dd<DdType::CUDD> getIdentity(std::string const& metaVariableName);
             
             /*!
              * Adds a meta variable with the given name and range.
@@ -106,7 +106,7 @@ namespace storm {
              * @param metaVariableName The name of the meta variable to retrieve.
              * @return The meta variable with the given name.
              */
-            DdMetaVariable<CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
+            DdMetaVariable<DdType::CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
             
             /*!
              * Retrieves the names of all meta variables that have been added to the manager.
@@ -139,7 +139,7 @@ namespace storm {
             Cudd& getCuddManager();
             
             // A mapping from variable names to the meta variable information.
-            std::unordered_map<std::string, DdMetaVariable<CUDD>> metaVariableMap;
+            std::unordered_map<std::string, DdMetaVariable<DdType::CUDD>> metaVariableMap;
             
             // The manager responsible for the DDs created/modified with this DdManager.
             Cudd cuddManager;
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
index 7671289fc..9132eab03 100644
--- a/src/storage/dd/DdMetaVariable.cpp
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -47,6 +47,6 @@ namespace storm {
         }
         
         // Explicitly instantiate DdMetaVariable.
-        template class DdMetaVariable<CUDD>;
+        template class DdMetaVariable<DdType::CUDD>;
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/DdType.h b/src/storage/dd/DdType.h
index 327832ec5..feb2fe70a 100644
--- a/src/storage/dd/DdType.h
+++ b/src/storage/dd/DdType.h
@@ -3,7 +3,7 @@
 
 namespace storm {
     namespace dd {
-        enum DdType {
+        enum class DdType {
             CUDD
         };
     }
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index bd2e3cbc9..0c641d3ec 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -3,6 +3,7 @@
 
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/SubstitutionVisitor.h"
+#include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
 #include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/ExceptionMacros.h"
 
@@ -30,6 +31,11 @@ namespace storm {
             return SubstitutionVisitor<MapType>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
         }
         
+        template<template<typename... Arguments> class MapType>
+        Expression Expression::substitute(MapType<std::string, std::string> const& identifierToIdentifierMap) const {
+            return IdentifierSubstitutionVisitor<MapType>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+        }
+        
         bool Expression::evaluateAsBool(Valuation const& valuation) const {
             return this->getBaseExpression().evaluateAsBool(valuation);
         }
@@ -222,6 +228,8 @@ namespace storm {
         
         template Expression Expression::substitute<std::map>(std::map<std::string, storm::expressions::Expression> const&) const;
         template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, storm::expressions::Expression> const&) const;
+        template Expression Expression::substitute<std::map>(std::map<std::string, std::string> const&) const;
+        template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, std::string> const&) const;
         
         std::ostream& operator<<(std::ostream& stream, Expression const& expression) {
             stream << expression.getBaseExpression();
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 52e656a15..3002e4d35 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -71,6 +71,16 @@ namespace storm {
             template<template<typename... Arguments> class MapType>
             Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const;
             
+            /*!
+             * Substitutes all occurrences of identifiers with different names given by a mapping.
+             *
+             * @param identifierToIdentifierMap A mapping from identifiers to identifiers they are substituted with.
+             * @return An expression in which all identifiers in the key set of the mapping are replaced by the
+             * identifiers they are mapped to.
+             */
+            template<template<typename... Arguments> class MapType>
+            Expression substitute(MapType<std::string, std::string> const& identifierToIdentifierMap) const;
+            
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
              * valuation and returns the resulting boolean value. If the return type of the expression is not a boolean
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
new file mode 100644
index 000000000..e753583f9
--- /dev/null
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
@@ -0,0 +1,177 @@
+#include <map>
+#include <unordered_map>
+
+#include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
+
+#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/BinaryRelationExpression.h"
+#include "src/storage/expressions/BooleanConstantExpression.h"
+#include "src/storage/expressions/IntegerConstantExpression.h"
+#include "src/storage/expressions/DoubleConstantExpression.h"
+#include "src/storage/expressions/BooleanLiteralExpression.h"
+#include "src/storage/expressions/IntegerLiteralExpression.h"
+#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/VariableExpression.h"
+#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+
+namespace storm {
+    namespace expressions  {
+        template<template<typename... Arguments> class MapType>
+        IdentifierSubstitutionVisitor<MapType>::IdentifierSubstitutionVisitor(MapType<std::string, std::string> const& identifierToIdentifierMap) : identifierToIdentifierMap(identifierToIdentifierMap) {
+            // Intentionally left empty.
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        Expression IdentifierSubstitutionVisitor<MapType>::substitute(BaseExpression const* expression) {
+            expression->accept(this);
+            return Expression(this->expressionStack.top());
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getSecondOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> secondExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the arguments did not change, we simply push the expression itself.
+            if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(BinaryNumericalFunctionExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getSecondOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> secondExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the arguments did not change, we simply push the expression itself.
+            if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(BinaryRelationExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getSecondOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> secondExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the arguments did not change, we simply push the expression itself.
+            if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getRelationType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
+            // If the boolean constant is in the key set of the substitution, we need to replace it.
+            auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
+            if (namePair != this->identifierToIdentifierMap.end()) {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BooleanConstantExpression(namePair->second)));
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
+            // If the double constant is in the key set of the substitution, we need to replace it.
+            auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
+            if (namePair != this->identifierToIdentifierMap.end()) {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new DoubleConstantExpression(namePair->second)));
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
+            // If the integer constant is in the key set of the substitution, we need to replace it.
+            auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
+            if (namePair != this->identifierToIdentifierMap.end()) {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new IntegerConstantExpression(namePair->second)));
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(VariableExpression const* expression) {
+            // If the variable is in the key set of the substitution, we need to replace it.
+            auto const& namePair = this->identifierToIdentifierMap.find(expression->getVariableName());
+            if (namePair != this->identifierToIdentifierMap.end()) {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new VariableExpression(expression->getReturnType(), namePair->second)));
+            } else {
+                this->expressionStack.push(expression->getSharedPointer());
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(UnaryBooleanFunctionExpression const* expression) {
+            expression->getOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the argument did not change, we simply push the expression itself.
+            if (operandExpression.get() == expression->getOperand().get()) {
+                expressionStack.push(expression->getSharedPointer());
+            } else {
+                expressionStack.push(std::shared_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(expression->getReturnType(), operandExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(UnaryNumericalFunctionExpression const* expression) {
+            expression->getOperand()->accept(this);
+            std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the argument did not change, we simply push the expression itself.
+            if (operandExpression.get() == expression->getOperand().get()) {
+                expressionStack.push(expression->getSharedPointer());
+            } else {
+                expressionStack.push(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(expression->getReturnType(), operandExpression, expression->getOperatorType())));
+            }
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(BooleanLiteralExpression const* expression) {
+            this->expressionStack.push(expression->getSharedPointer());
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(IntegerLiteralExpression const* expression) {
+            this->expressionStack.push(expression->getSharedPointer());
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(DoubleLiteralExpression const* expression) {
+            this->expressionStack.push(expression->getSharedPointer());
+        }
+        
+        // Explicitly instantiate the class with map and unordered_map.
+        template class IdentifierSubstitutionVisitor<std::map>;
+        template class IdentifierSubstitutionVisitor<std::unordered_map>;
+    }
+}
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.h b/src/storage/expressions/IdentifierSubstitutionVisitor.h
new file mode 100644
index 000000000..87976122c
--- /dev/null
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.h
@@ -0,0 +1,54 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_IDENTIFIERSUBSTITUTIONVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_IDENTIFIERSUBSTITUTIONVISITOR_H_
+
+#include <stack>
+
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+
+namespace storm {
+    namespace expressions {
+        template<template<typename... Arguments> class MapType>
+        class IdentifierSubstitutionVisitor : public ExpressionVisitor {
+        public:
+            /*!
+             * Creates a new substitution visitor that uses the given map to replace identifiers.
+             *
+             * @param identifierToExpressionMap A mapping from identifiers to expressions.
+             */
+            IdentifierSubstitutionVisitor(MapType<std::string, std::string> const& identifierToExpressionMap);
+            
+            /*!
+             * Substitutes the identifiers in the given expression according to the previously given map and returns the
+             * resulting expression.
+             *
+             * @param expression The expression in which to substitute the identifiers.
+             * @return The expression in which all identifiers in the key set of the previously given mapping are
+             * substituted with the mapped-to expressions.
+             */
+            Expression substitute(BaseExpression const* expression);
+            
+            virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BinaryRelationExpression const* expression) override;
+            virtual void visit(BooleanConstantExpression const* expression) override;
+            virtual void visit(DoubleConstantExpression const* expression) override;
+            virtual void visit(IntegerConstantExpression const* expression) override;
+            virtual void visit(VariableExpression const* expression) override;
+            virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BooleanLiteralExpression const* expression) override;
+            virtual void visit(IntegerLiteralExpression const* expression) override;
+            virtual void visit(DoubleLiteralExpression const* expression) override;
+            
+        private:
+            // A stack of expression used to pass the results to the higher levels.
+            std::stack<std::shared_ptr<BaseExpression const>> expressionStack;
+            
+            // A mapping of identifier names to expressions with which they shall be replaced.
+            MapType<std::string, std::string> const& identifierToIdentifierMap;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_IDENTIFIERSUBSTITUTIONVISITOR_H_ */
\ No newline at end of file
diff --git a/src/storage/prism/Assignment.cpp b/src/storage/prism/Assignment.cpp
new file mode 100644
index 000000000..4455ec65d
--- /dev/null
+++ b/src/storage/prism/Assignment.cpp
@@ -0,0 +1,30 @@
+#include "Assignment.h"
+
+namespace storm {
+    namespace prism {
+        Assignment::Assignment(std::string const& variableName, storm::expressions::Expression const& expression) : variableName(variableName), expression(expression) {
+            // Intentionally left empty.
+        }
+        
+        Assignment::Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming) : variableName(oldAssignment.getVariableName()), expression(oldAssignment.getExpression().substitute<std::map>(renaming)) {
+            auto renamingPair = renaming.find(oldAssignment.variableName);
+            if (renamingPair != renaming.end()) {
+                this->variableName = renamingPair->second;
+            }
+        }
+        
+        std::string const& Assignment::getVariableName() const {
+            return variableName;
+        }
+        
+        storm::expressions::Expression const& Assignment::getExpression() const {
+            return this->expression;
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, Assignment const& assignment) {
+            stream << "(" << assignment.getVariableName() << "' = " << assignment.getExpression() << ")";
+            return stream;
+        }
+
+    } // namespace prism
+} // namespace storm
diff --git a/src/storage/prism/Assignment.h b/src/storage/prism/Assignment.h
new file mode 100644
index 000000000..48a235c8a
--- /dev/null
+++ b/src/storage/prism/Assignment.h
@@ -0,0 +1,61 @@
+#ifndef STORM_STORAGE_PRISM_ASSIGNMENT_H_
+#define STORM_STORAGE_PRISM_ASSIGNMENT_H_
+
+#include <map>
+
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace prism {
+        class Assignment {
+        public:
+            /*!
+             * Constructs an assignment using the given variable name and expression.
+             *
+             * @param variableName The variable that this assignment targets.
+             * @param expression The expression to assign to the variable.
+             */
+            Assignment(std::string const& variableName, storm::expressions::Expression const& expression);
+            
+            /*!
+             * Creates a copy of the given assignment and performs the provided renaming.
+             *
+             * @param oldAssignment The assignment to copy.
+             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             */
+            Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming);
+            
+            // Create default implementations of constructors/assignment.
+            Assignment() = default;
+            Assignment(Assignment const& otherVariable) = default;
+            Assignment& operator=(Assignment const& otherVariable)= default;
+            Assignment(Assignment&& otherVariable) = default;
+            Assignment& operator=(Assignment&& otherVariable) = default;
+            
+            /*!
+             * Retrieves the name of the variable that this assignment targets.
+             *
+             * @return The name of the variable that this assignment targets.
+             */
+            std::string const& getVariableName() const;
+            
+            /*!
+             * Retrieves the expression that is assigned to the variable.
+             *
+             * @return The expression that is assigned to the variable.
+             */
+            storm::expressions::Expression const& getExpression() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, Assignment const& assignment);
+            
+        private:
+            // The name of the variable that this assignment targets.
+            std::string variableName;
+            
+            // The expression that is assigned to the variable.
+            storm::expressions::Expression expression;
+        };
+    } // namespace ir
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_ASSIGNMENT_H_ */
diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
new file mode 100644
index 000000000..adf12b165
--- /dev/null
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -0,0 +1,23 @@
+#include "src/storage/prism/BooleanVariable.h"
+
+namespace storm {
+    namespace prism {
+        BooleanVariable::BooleanVariable(std::string const& variableName) : BooleanVariable(variableName, storm::expressions::Expression::createFalse()) {
+            // Nothing to do here.
+        }
+
+        BooleanVariable::BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression) {
+            // Nothing to do here.
+        }
+        
+        BooleanVariable::BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : Variable(oldVariable, newName, renaming) {
+            // Nothing to do here.
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable) {
+            stream << variable.getName() << ": bool " << variable.getInitialValueExpression() << ";";
+            return stream;
+        }
+        
+    } // namespace prism
+} // namespace storm
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
new file mode 100644
index 000000000..74c046e00
--- /dev/null
+++ b/src/storage/prism/BooleanVariable.h
@@ -0,0 +1,50 @@
+#ifndef STORM_STORAGE_PRISM_BOOLEANVARIABLE_H_
+#define STORM_STORAGE_PRISM_BOOLEANVARIABLE_H_
+
+#include <map>
+
+#include "src/storage/prism/Variable.h"
+
+namespace storm {
+    namespace prism {
+        class BooleanVariable : public Variable {
+        public:
+            // Create default implementations of constructors/assignment.
+            BooleanVariable() = default;
+            BooleanVariable(BooleanVariable const& otherVariable) = default;
+            BooleanVariable& operator=(BooleanVariable const& otherVariable)= default;
+            BooleanVariable(BooleanVariable&& otherVariable) = default;
+            BooleanVariable& operator=(BooleanVariable&& otherVariable) = default;
+            
+            /*!
+             * Creates a boolean variable with the given name and default initial value.
+             *
+             * @param variableName The name of the variable.
+             */
+            BooleanVariable(std::string const& variableName);
+
+            /*!
+             * Creates a boolean variable with the given name and the given constant initial value expression.
+             *
+             * @param variableName The name of the variable.
+             * @param initialValueExpression The constant expression that defines the initial value of the variable.
+             */
+            BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression);
+
+            /*!
+             * Creates a copy of the given boolean variable and performs the provided renaming.
+             *
+             * @param oldVariable The variable to copy.
+             * @param newName New name of this variable.
+             * @param renaming A mapping from names that are to be renamed to the names they are to be
+             * replaced with.
+             */
+            BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming);
+            
+            friend std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable);
+        };
+        
+    } // namespace prism
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_BOOLEANVARIABLE_H_ */
diff --git a/src/ir/Command.cpp b/src/storage/prism/Command.cpp
similarity index 100%
rename from src/ir/Command.cpp
rename to src/storage/prism/Command.cpp
diff --git a/src/ir/Command.h b/src/storage/prism/Command.h
similarity index 100%
rename from src/ir/Command.h
rename to src/storage/prism/Command.h
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
new file mode 100644
index 000000000..7f11a8bc2
--- /dev/null
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -0,0 +1,30 @@
+#include "src/storage/prism/IntegerVariable.h"
+
+namespace storm {
+    namespace prism {
+        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression) : IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, lowerBoundExpression) {
+            // Intentionally left empty.
+        }
+
+        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
+            // Intentionally left empty.
+        }
+        
+        IntegerVariable::IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : Variable(oldVariable, newName, renaming), lowerBoundExpression(oldVariable.getLowerBoundExpression().substitute<std::map>(renaming)), upperBoundExpression(oldVariable.getUpperBoundExpression().substitute<std::map>(renaming)) {
+            // Intentionally left empty.
+        }
+        
+        storm::expressions::Expression const& IntegerVariable::getLowerBoundExpression() const {
+            return this->lowerBoundExpression;
+        }
+        
+        storm::expressions::Expression const& IntegerVariable::getUpperBoundExpression() const {
+            return this->upperBoundExpression;
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable) {
+            stream << this->getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << variable.getInitialValueExpression() << ";";
+            return stream;
+        }
+    } // namespace prism
+} // namespace storm
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
new file mode 100644
index 000000000..b2dbb4cb5
--- /dev/null
+++ b/src/storage/prism/IntegerVariable.h
@@ -0,0 +1,74 @@
+#ifndef STORM_STORAGE_PRISM_INTEGERVARIABLE_H_
+#define STORM_STORAGE_PRISM_INTEGERVARIABLE_H_
+
+#include <map>
+
+#include "src/storage/prism/Variable.h"
+
+namespace storm {
+    namespace prism {
+        class IntegerVariable : public Variable {
+        public:
+            // Create default implementations of constructors/assignment.
+            IntegerVariable() = default;
+            IntegerVariable(IntegerVariable const& otherVariable) = default;
+            IntegerVariable& operator=(IntegerVariable const& otherVariable)= default;
+            IntegerVariable(IntegerVariable&& otherVariable) = default;
+            IntegerVariable& operator=(IntegerVariable&& otherVariable) = default;
+
+            /*!
+             * Creates an integer variable with the given name and a default initial value.
+             *
+             * @param variableName The name of the variable.
+             * @param lowerBoundExpression A constant expression defining the lower bound of the domain of the variable.
+             * @param upperBoundExpression A constant expression defining the upper bound of the domain of the variable.
+             */
+            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression);
+
+            /*!
+             * Creates an integer variable with the given name and the given initial value expression.
+             *
+             * @param variableName The name of the variable.
+             * @param lowerBoundExpression A constant expression defining the lower bound of the domain of the variable.
+             * @param upperBoundExpression A constant expression defining the upper bound of the domain of the variable.
+             * @param initialValueExpression A constant expression that defines the initial value of the variable.
+             */
+            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression);
+            
+            /*!
+             * Creates a copy of the given integer variable and performs the provided renaming.
+             *
+             * @param oldVariable The variable to copy.
+             * @param newName New name of this variable.
+             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             */
+            IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming);
+            
+            /*!
+             * Retrieves an expression defining the lower bound for this integer variable.
+             *
+             * @return An expression defining the lower bound for this integer variable.
+             */
+            storm::expressions::Expression const& getLowerBoundExpression() const;
+            
+            /*!
+             * Retrieves an expression defining the upper bound for this integer variable.
+             *
+             * @return An expression defining the upper bound for this integer variable.
+             */
+            storm::expressions::Expression const& getUpperBoundExpression() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable);
+            
+        private:
+            // A constant expression that specifies the lower bound of the domain of the variable.
+            storm::expressions::Expression lowerBoundExpression;
+            
+            // A constant expression that specifies the upper bound of the domain of the variable.
+            storm::expressions::Expression upperBoundExpression;
+        };
+        
+    } // namespace prism
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_INTEGERVARIABLE_H_ */
diff --git a/src/ir/Module.cpp b/src/storage/prism/Module.cpp
similarity index 100%
rename from src/ir/Module.cpp
rename to src/storage/prism/Module.cpp
diff --git a/src/ir/Module.h b/src/storage/prism/Module.h
similarity index 100%
rename from src/ir/Module.h
rename to src/storage/prism/Module.h
diff --git a/src/ir/Program.cpp b/src/storage/prism/Program.cpp
similarity index 100%
rename from src/ir/Program.cpp
rename to src/storage/prism/Program.cpp
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
new file mode 100644
index 000000000..169a3fe32
--- /dev/null
+++ b/src/storage/prism/Program.h
@@ -0,0 +1,227 @@
+/*
+ * Program.h
+ *
+ *  Created on: 04.01.2013
+ *      Author: Christian Dehnert
+ */
+
+#ifndef STORM_IR_PROGRAM_H_
+#define STORM_IR_PROGRAM_H_
+
+#include <map>
+#include <vector>
+#include <memory>
+#include <set>
+#include <boost/container/flat_set.hpp>
+
+#include "src/storage/expressions/Expression.h"
+#include "Module.h"
+#include "RewardModel.h"
+
+namespace storm {
+    namespace ir {
+        
+        /*!
+         * A class representing a program.
+         */
+        class Program {
+        public:
+            
+            /*!
+             * An enum for the different model types.
+             */
+            enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP};
+            
+            /*!
+             * Creates a program with the given model type, undefined constants, modules, rewards and labels.
+             *
+             * @param modelType The type of the model that this program gives rise to.
+             * @param booleanUndefinedConstantExpressions A map of undefined boolean constants to their
+             * expression nodes.
+             * @param integerUndefinedConstantExpressions A map of undefined integer constants to their
+             * expression nodes.
+             * @param doubleUndefinedConstantExpressions A map of undefined double constants to their
+             * expression nodes.
+             * @param globalBooleanVariables A list of global boolean variables.
+             * @param globalIntegerVariables A list of global integer variables.
+             * @param globalBooleanVariableToIndexMap A mapping from global boolean variable names to the index in the
+             * list of global boolean variables.
+             * @param globalIntegerVariableToIndexMap A mapping from global integer variable names to the index in the
+             * list of global integer variables.
+             * @param modules The modules of the program.
+             * @param rewards The reward models of the program.
+             * @param labels The labels defined for this model.
+             */
+            Program(ModelType modelType,
+                    std::set<std::string> const& booleanUndefinedConstantExpressions,
+                    std::set<std::string> const& integerUndefinedConstantExpressions,
+                    std::set<std::string> const& doubleUndefinedConstantExpressions,
+                    std::map<std::string, BooleanVariable> const& globalBooleanVariables,
+                    std::map<std::string, IntegerVariable> const& globalIntegerVariables,
+                    std::vector<storm::ir::Module> const& modules,
+                    std::map<std::string, storm::ir::RewardModel> const& rewards,
+                    std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels);
+            
+            // Provide default implementations for constructors and assignments.
+            Program() = default;
+            Program(Program const& otherProgram) = default;
+            Program& operator=(Program const& otherProgram) = default;
+            Program(Program&& otherProgram) = default;
+            Program& operator=(Program&& otherProgram) = default;
+            
+            /*!
+             * Retrieves the model type of the model.
+             *
+             * @return The type of the model.
+             */
+            ModelType getModelType() const;
+
+            bool hasUndefinedConstants() const;
+            
+            bool hasUndefinedBooleanConstants() const;
+            bool hasUndefinedIntegerConstants() const;
+            bool hasUndefinedDoubleConstants() const;
+            
+            std::set<std::string> const& getUndefinedBooleanConstants() const;
+            std::set<std::string> const& getUndefinedIntegerConstants() const;
+            std::set<std::string> const& getUndefinedDoubleConstants() const;
+            
+            std::map<std::string, storm::ir::BooleanVariable> const& getGlobalBooleanVariables() const;
+            
+            /*!
+             * Retrieves a reference to the global boolean variable with the given index.
+             *
+             * @return A reference to the global boolean variable with the given index.
+             */
+            storm::ir::BooleanVariable const& getGlobalBooleanVariable(std::string const& variableName) const;
+            
+            std::map<std::string, storm::ir::IntegerVariable> const& getGlobalIntegerVariables() const;
+
+            /*!
+             * Retrieves a reference to the global integer variable with the given index.
+             *
+             * @return A reference to the global integer variable with the given index.
+             */
+            storm::ir::IntegerVariable const& getGlobalIntegerVariable(std::string const& variableName) const;
+
+            /*!
+             * Retrieves the number of global boolean variables of the program.
+             *
+             * @return The number of global boolean variables of the program.
+             */
+            uint_fast64_t getNumberOfGlobalBooleanVariables() const;
+            
+            /*!
+             * Retrieves the number of global integer variables of the program.
+             *
+             * @return The number of global integer variables of the program.
+             */
+            uint_fast64_t getNumberOfGlobalIntegerVariables() const;
+
+            /*!
+             * Retrieves the number of modules in the program.
+             *
+             * @return The number of modules in the program.
+             */
+            uint_fast64_t getNumberOfModules() const;
+            
+            /*!
+             * Retrieves a reference to the module with the given index.
+             *
+             * @param index The index of the module to retrieve.
+             * @return The module with the given index.
+             */
+            storm::ir::Module const& getModule(uint_fast64_t index) const;
+            
+            /*!
+             * Retrieves the set of actions present in the program.
+             *
+             * @return The set of actions present in the program.
+             */
+            std::set<std::string> const& getActions() const;
+            
+            /*!
+             * Retrieves the indices of all modules within this program that contain commands that are labelled with the given
+             * action.
+             *
+             * @param action The name of the action the modules are supposed to possess.
+             * @return A set of indices of all matching modules.
+             */
+            std::set<uint_fast64_t> const& getModuleIndicesByAction(std::string const& action) const;
+            
+            /*!
+             * Retrieves the index of the module in which the given variable name was declared.
+             *
+             * @param variableName The name of the variable to search.
+             * @return The index of the module in which the given variable name was declared.
+             */
+            uint_fast64_t getModuleIndexByVariable(std::string const& variableName) const;
+            
+            std::map<std::string, storm::ir::RewardModel> const& getRewardModels() const;
+            
+            /*!
+             * Retrieves the reward model with the given name.
+             *
+             * @param name The name of the reward model to return.
+             * @return The reward model with the given name.
+             */
+            storm::ir::RewardModel const& getRewardModel(std::string const& name) const;
+            
+            /*!
+             * Retrieves all labels that are defined by the probabilitic program.
+             *
+             * @return A set of labels that are defined in the program.
+             */
+            std::map<std::string, Expression> const& getLabels() const;
+            
+            /*!
+             * Creates a new program that drops all commands whose indices are not in the given set.
+             *
+             * @param indexSet The set of indices for which to keep the commands.
+             */
+            Program restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
+            
+            friend std::ostream& operator<<(std::ostream& stream, Program const& program);
+            
+        private:
+            // The type of the model.
+            ModelType modelType;
+            
+            // A list of undefined boolean constants of the model.
+            std::set<std::string> undefinedBooleanConstants;
+            
+            // A list of undefined integer constants of the model.
+            std::set<std::string> undefinedIntegerConstants;
+
+            // A list of undefined double constants of the model.
+            std::set<std::string> undefinedDoubleConstants;
+            
+            // A list of global boolean variables.
+            std::map<std::string, BooleanVariable> globalBooleanVariables;
+            
+            // A list of global integer variables.
+            std::std::string, IntegerVariable> globalIntegerVariables;
+            
+            // The modules associated with the program.
+            std::vector<storm::ir::Module> modules;
+            
+            // The reward models associated with the program.
+            std::map<std::string, storm::ir::RewardModel> rewardModels;
+            
+            // The labels that are defined for this model.
+            std::map<std::string, Expression> labels;
+            
+            // The set of actions present in this program.
+            std::set<std::string> actions;
+            
+            // A map of actions to the set of modules containing commands labelled with this action.
+            std::map<std::string, std::set<uint_fast64_t>> actionsToModuleIndexMap;
+            
+            // A mapping from variable names to the modules in which they were declared.
+            std::map<std::string, uint_fast64_t> variableToModuleIndexMap;
+        };
+        
+    } // namespace ir
+} // namespace storm
+
+#endif /* STORM_IR_PROGRAM_H_ */
diff --git a/src/ir/RewardModel.cpp b/src/storage/prism/RewardModel.cpp
similarity index 100%
rename from src/ir/RewardModel.cpp
rename to src/storage/prism/RewardModel.cpp
diff --git a/src/ir/RewardModel.h b/src/storage/prism/RewardModel.h
similarity index 100%
rename from src/ir/RewardModel.h
rename to src/storage/prism/RewardModel.h
diff --git a/src/storage/prism/StateReward.cpp b/src/storage/prism/StateReward.cpp
new file mode 100644
index 000000000..50457cabc
--- /dev/null
+++ b/src/storage/prism/StateReward.cpp
@@ -0,0 +1,38 @@
+/*
+ * StateReward.cpp
+ *
+ *  Created on: 12.01.2013
+ *      Author: Christian Dehnert
+ */
+
+#include <sstream>
+
+#include "StateReward.h"
+
+namespace storm {
+    namespace ir {
+        
+        StateReward::StateReward() : statePredicate(), rewardValue() {
+            // Nothing to do here.
+        }
+        
+        StateReward::StateReward(storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue) : statePredicate(statePredicate), rewardValue(rewardValue) {
+            // Nothing to do here.
+        }
+        
+        std::string StateReward::toString() const {
+            std::stringstream result;
+            result << "\t" << statePredicate << ": " << rewardValue << ";";
+            return result.str();
+        }
+        
+        storm::expressions::Expression const& StateReward::getStatePredicate() const {
+            return this->statePredicate;
+        }
+        
+        storm::expressions::Expression const& StateReward::getRewardValue() const {
+            return this->rewardValue;
+        }
+        
+    } // namespace ir
+} // namespace storm
diff --git a/src/ir/StateReward.h b/src/storage/prism/StateReward.h
similarity index 78%
rename from src/ir/StateReward.h
rename to src/storage/prism/StateReward.h
index 117544d6d..d8c09f4e2 100644
--- a/src/ir/StateReward.h
+++ b/src/storage/prism/StateReward.h
@@ -10,7 +10,7 @@
 
 #include <memory>
 
-#include "expressions/BaseExpression.h"
+#include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace ir {
@@ -34,21 +34,21 @@ namespace storm {
              * @param rewardValue An expression specifying the values of the rewards to attach to the
              * states.
              */
-            StateReward(std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue);
+            StateReward(storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue);
             
             /*!
              * Performs a deep-copy of the given reward.
              *
              * @param otherReward The reward to copy.
              */
-            StateReward(StateReward const& otherReward);
+            StateReward(StateReward const& otherReward) = default;
 
             /*!
              * Performs a deep-copy of the given reward and assigns it to the current one.
              *
              * @param otherReward The reward to assign.
              */
-            StateReward& operator=(StateReward const& otherReward);
+            StateReward& operator=(StateReward const& otherReward) = default;
             
             /*!
              * Retrieves a string representation of this state reward.
@@ -62,21 +62,21 @@ namespace storm {
              *
              * @return The state predicate that is associated with this state reward.
              */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getStatePredicate() const;
+            storm::expressions::Expression const& getStatePredicate() const;
             
             /*!
              * Retrieves the reward value associated with this state reward.
              *
              * @return The reward value associated with this state reward.
              */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getRewardValue() const;
+            storm::expressions::Expression const& getRewardValue() const;
             
         private:
             // The predicate that characterizes the states that obtain this reward.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> statePredicate;
+            storm::expressions::Expression statePredicate;
             
             // The expression that specifies the value of the reward obtained.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> rewardValue;
+            storm::expressions::Expression rewardValue;
         };
         
     } // namespace ir
diff --git a/src/storage/prism/TransitionReward.cpp b/src/storage/prism/TransitionReward.cpp
new file mode 100644
index 000000000..93d951731
--- /dev/null
+++ b/src/storage/prism/TransitionReward.cpp
@@ -0,0 +1,42 @@
+/*
+ * TransitionReward.cpp
+ *
+ *  Created on: 12.01.2013
+ *      Author: Christian Dehnert
+ */
+
+#include <sstream>
+
+#include "TransitionReward.h"
+
+namespace storm {
+    namespace ir {
+        
+        TransitionReward::TransitionReward() : commandName(), statePredicate(), rewardValue() {
+            // Nothing to do here.
+        }
+        
+        TransitionReward::TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue) : commandName(commandName), statePredicate(statePredicate), rewardValue(rewardValue) {
+            // Nothing to do here.
+        }
+        
+        std::string TransitionReward::toString() const {
+            std::stringstream result;
+            result << "\t[" << commandName << "] " << statePredicate << ": " << rewardValue << ";";
+            return result.str();
+        }
+        
+        std::string const& TransitionReward::getActionName() const {
+            return this->commandName;
+        }
+        
+        storm::expressions::Expression const& TransitionReward::getStatePredicate() const {
+            return this->statePredicate;
+        }
+        
+        storm::expressions::Expression const& TransitionReward::getRewardValue() const {
+            return this->rewardValue;
+        }
+        
+    } // namespace ir
+} // namespace storm
diff --git a/src/ir/TransitionReward.h b/src/storage/prism/TransitionReward.h
similarity index 79%
rename from src/ir/TransitionReward.h
rename to src/storage/prism/TransitionReward.h
index 298d17024..b21eeb12f 100644
--- a/src/ir/TransitionReward.h
+++ b/src/storage/prism/TransitionReward.h
@@ -10,7 +10,7 @@
 
 #include <memory>
 
-#include "expressions/BaseExpression.h"
+#include "src/storage/expressions/Expression.h"
 
 namespace storm {
 
@@ -36,21 +36,21 @@ public:
 	 * @param rewardValue An expression specifying the values of the rewards to attach to the
 	 * transitions.
 	 */
-	TransitionReward(std::string const& commandName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue);
+	TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue);
 
     /*!
      * Performs a deep-copy of the given transition reward.
      *
      * @param otherReward The transition reward to copy.
      */
-    TransitionReward(TransitionReward const& otherReward);
+    TransitionReward(TransitionReward const& otherReward) = default;
     
     /*!
      * Performs a deep-copy of the given transition reward and assigns it to the current one.
      *
      * @param otherReward The reward to assign.
      */
-    TransitionReward& operator=(TransitionReward const& otherReward);
+    TransitionReward& operator=(TransitionReward const& otherReward) = default;
     
 	/*!
 	 * Retrieves a string representation of this transition reward.
@@ -71,14 +71,14 @@ public:
      *
      * @return The state predicate that is associated with this state reward.
      */
-    std::unique_ptr<storm::ir::expressions::BaseExpression> const& getStatePredicate() const;
+    storm::expressions::Expression const& getStatePredicate() const;
     
     /*!
      * Retrieves the reward value associated with this state reward.
      *
      * @return The reward value associated with this state reward.
      */
-    std::unique_ptr<storm::ir::expressions::BaseExpression> const& getRewardValue() const;
+    storm::expressions::Expression const& getRewardValue() const;
 
 private:
 	// The name of the command this transition-based reward is attached to.
@@ -86,10 +86,10 @@ private:
 
 	// A predicate that needs to be satisfied by states for the reward to be obtained (by taking
 	// a corresponding command transition).
-	std::unique_ptr<storm::ir::expressions::BaseExpression> statePredicate;
+	storm::expressions::Expression statePredicate;
 
 	// The expression specifying the value of the reward obtained along the transitions.
-	std::unique_ptr<storm::ir::expressions::BaseExpression> rewardValue;
+	storm::expressions::Expression rewardValue;
 };
 
 } // namespace ir
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
new file mode 100644
index 000000000..7a4bb64ad
--- /dev/null
+++ b/src/storage/prism/Update.cpp
@@ -0,0 +1,94 @@
+#include "Update.h"
+#include "src/exceptions/OutOfRangeException.h"
+
+namespace storm {
+    namespace prism {
+        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments) : likelihoodExpression(likelihoodExpression), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments), globalIndex(globalIndex) {
+            // Nothing to do here.
+        }
+        
+        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming) : likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), booleanAssignments(), integerAssignments(), globalIndex(newGlobalIndex) {
+            for (auto const& variableAssignmentPair : update.getBooleanAssignments()) {
+                auto const& namePair = renaming.find(variableAssignmentPair.first);
+                if (namePair != renaming.end()) {
+                    this->booleanAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming));
+                } else {
+                    this->booleanAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming));
+                }
+            }
+            for (auto const& variableAssignmentPair : update.getIntegerAssignments()) {
+                auto const& namePair = renaming.find(variableAssignmentPair.first);
+                if (renaming.count(variableAssignmentPair.first) > 0) {
+                    this->integerAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming));
+                } else {
+                    this->integerAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming));
+                }
+            }
+            this->likelihoodExpression = update.getLikelihoodExpression().substitute<std::map>(renaming);
+        }
+        
+        storm::expressions::Expression const& Update::getLikelihoodExpression() const {
+            return likelihoodExpression;
+        }
+        
+        std::size_t Update::getNumberOfBooleanAssignments() const {
+            return booleanAssignments.size();
+        }
+        
+        std::size_t Update::getNumberOfIntegerAssignments() const {
+            return integerAssignments.size();
+        }
+        
+        std::map<std::string, storm::prism::Assignment> const& Update::getBooleanAssignments() const {
+            return booleanAssignments;
+        }
+        
+        std::map<std::string, storm::prism::Assignment> const& Update::getIntegerAssignments() const {
+            return integerAssignments;
+        }
+        
+        storm::prism::Assignment const& Update::getBooleanAssignment(std::string const& variableName) const {
+            auto variableAssignmentPair = booleanAssignments.find(variableName);
+            if (variableAssignmentPair == booleanAssignments.end()) {
+                throw storm::exceptions::OutOfRangeException() << "Cannot find boolean assignment for variable '" << variableName << "' in update " << *this << ".";
+            }
+            
+            return variableAssignmentPair->second;
+        }
+        
+        storm::prism::Assignment const& Update::getIntegerAssignment(std::string const& variableName) const {
+            auto variableAssignmentPair = integerAssignments.find(variableName);
+            if (variableAssignmentPair == integerAssignments.end()) {
+                throw storm::exceptions::OutOfRangeException() << "Cannot find integer assignment for variable '" << variableName << "' in update " << *this << ".";
+            }
+            
+            return variableAssignmentPair->second;
+        }
+        
+        uint_fast64_t Update::getGlobalIndex() const {
+            return this->globalIndex;
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, Update const& update) {
+            stream << update.getLikelihoodExpression() << " : ";
+            uint_fast64_t i = 0;
+            for (auto const& assignment : update.getBooleanAssignments()) {
+                stream << assignment.second;
+                if (i < update.getBooleanAssignments().size() - 1 || update.getIntegerAssignments().size() > 0) {
+                    stream << " & ";
+                }
+                ++i;
+            }
+            i = 0;
+            for (auto const& assignment : update.getIntegerAssignments()) {
+                result << assignment.second;
+                if (i < update.getIntegerAssignments().size() - 1) {
+                    stream << " & ";
+                }
+                ++i;
+            }
+            return stream;
+        }
+        
+    } // namespace ir
+} // namespace storm
diff --git a/src/ir/Update.h b/src/storage/prism/Update.h
similarity index 54%
rename from src/ir/Update.h
rename to src/storage/prism/Update.h
index 07b9a7d24..878e394c3 100644
--- a/src/ir/Update.h
+++ b/src/storage/prism/Update.h
@@ -1,122 +1,88 @@
-/*
- * Update.h
- *
- *  Created on: 06.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_UPDATE_H_
-#define STORM_IR_UPDATE_H_
+#ifndef STORM_STORAGE_PRISM_UPDATE_H_
+#define STORM_STORAGE_PRISM_UPDATE_H_
 
 #include <map>
-#include <memory>
 
-#include "expressions/BaseExpression.h"
 #include "Assignment.h"
 
 namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing an update of a command.
-         */
+    namespace prism {
         class Update {
         public:
             /*!
-             * Default constructor. Creates an empty update.
-             */
-            Update();
-            
-            /*!
-             * Creates an update with the given expression specifying the likelihood and the mapping of
-             * variable to their assignments.
+             * Creates an update with the given expression specifying the likelihood and the mapping of variable to
+             * their assignments.
              *
              * @param globalIndex The global index of the update.
              * @param likelihoodExpression An expression specifying the likelihood of this update.
              * @param assignments A map of variable names to their assignments.
              */
-            Update(uint_fast64_t globalIndex, std::unique_ptr<storm::ir::expressions::BaseExpression>&& likelihoodExpression, std::map<std::string, storm::ir::Assignment> const& booleanAssignments, std::map<std::string, storm::ir::Assignment> const& integerAssignments);
+            Update(uint_fast64_t index, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments);
             
             /*!
              * Creates a copy of the given update and performs the provided renaming.
              *
              * @param update The update that is to be copied.
              * @param newGlobalIndex The global index of the resulting update.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param variableState An object knowing about the variables in the system.
-             */
-            Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState);
-            
-            /*!
-             * Peforms a deep-copy of the given update.
-             *
-             * @param otherUpdate The update to copy.
+             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
              */
-            Update(Update const& otherUpdate);
+            Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming);
             
-            /*!
-             * Performs a deep-copy of the given update and assigns it to the current one.
-             *
-             * @param otherUpdate The update to assign.
-             */
-            Update& operator=(Update const& otherUpdate);
+            // Create default implementations of constructors/assignment.
+            Update() = default;
+            Update(Update const& otherVariable) = default;
+            Update& operator=(Update const& otherVariable)= default;
+            Update(Update&& otherVariable) = default;
+            Update& operator=(Update&& otherVariable) = default;
             
             /*!
              * Retrieves the expression for the likelihood of this update.
              *
              * @return The expression for the likelihood of this update.
              */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getLikelihoodExpression() const;
+            storm::expressions::Expression const& getLikelihoodExpression() const;
             
             /*!
              * Retrieves the number of boolean assignments associated with this update.
              *
              * @return The number of boolean assignments associated with this update.
              */
-            uint_fast64_t getNumberOfBooleanAssignments() const;
+            std::size_t getNumberOfBooleanAssignments() const;
             
             /*!
              * Retrieves the number of integer assignments associated with this update.
              *
              * @return The number of integer assignments associated with this update.
              */
-            uint_fast64_t getNumberOfIntegerAssignments() const;
+            std::size_t getNumberOfIntegerAssignments() const;
             
             /*!
              * Retrieves a reference to the map of boolean variable names to their respective assignments.
              *
              * @return A reference to the map of boolean variable names to their respective assignments.
              */
-            std::map<std::string, storm::ir::Assignment> const& getBooleanAssignments() const;
+            std::map<std::string, storm::prism::Assignment> const& getBooleanAssignments() const;
             
             /*!
              * Retrieves a reference to the map of integer variable names to their respective assignments.
              *
              * @return A reference to the map of integer variable names to their respective assignments.
              */
-            std::map<std::string, storm::ir::Assignment> const& getIntegerAssignments() const;
+            std::map<std::string, storm::prism::Assignment> const& getIntegerAssignments() const;
             
             /*!
              * Retrieves a reference to the assignment for the boolean variable with the given name.
              *
              * @return A reference to the assignment for the boolean variable with the given name.
              */
-            storm::ir::Assignment const& getBooleanAssignment(std::string const& variableName) const;
+            storm::prism::Assignment const& getBooleanAssignment(std::string const& variableName) const;
             
             /*!
              * Retrieves a reference to the assignment for the integer variable with the given name.
              *
              * @return A reference to the assignment for the integer variable with the given name.
              */
-            storm::ir::Assignment const& getIntegerAssignment(std::string const& variableName) const;
+            storm::prism::Assignment const& getIntegerAssignment(std::string const& variableName) const;
             
             /*!
              * Retrieves the global index of the update, that is, a unique index over all modules.
@@ -125,28 +91,22 @@ namespace storm {
              */
             uint_fast64_t getGlobalIndex() const;
             
-            /*!
-             * Retrieves a string representation of this update.
-             *
-             * @return A string representation of this update.
-             */
-            std::string toString() const;
+            friend std::ostream& operator<<(std::ostream& stream, Update const& assignment);
             
         private:
             // An expression specifying the likelihood of taking this update.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> likelihoodExpression;
+            storm::expressions::Expression likelihoodExpression;
             
             // A mapping of boolean variable names to their assignments in this update.
-            std::map<std::string, storm::ir::Assignment> booleanAssignments;
+            std::map<std::string, storm::prism::Assignment> booleanAssignments;
             
             // A mapping of integer variable names to their assignments in this update.
-            std::map<std::string, storm::ir::Assignment> integerAssignments;
+            std::map<std::string, storm::prism::Assignment> integerAssignments;
             
             // The global index of the update.
             uint_fast64_t globalIndex;
         };
-        
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_UPDATE_H_ */
+#endif /* STORM_STORAGE_PRISM_UPDATE_H_ */
diff --git a/src/storage/prism/Variable.cpp b/src/storage/prism/Variable.cpp
new file mode 100644
index 000000000..9527e7f76
--- /dev/null
+++ b/src/storage/prism/Variable.cpp
@@ -0,0 +1,23 @@
+#include <map>
+
+#include "src/storage/prism/Variable.h"
+
+namespace storm {
+    namespace prism {
+        Variable::Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression) : variableName(variableName), initialValueExpression(initialValueExpression) {
+            // Nothing to do here.
+        }
+        
+        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : variableName(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)) {
+            // Intentionally left empty.
+        }
+        
+        std::string const& Variable::getName() const {
+            return variableName;
+        }
+        
+        storm::expressions::Expression const& Variable::getInitialValueExpression() const {
+            return this->initialValueExpression;
+        }
+    } // namespace prism
+} // namespace storm
diff --git a/src/storage/prism/Variable.h b/src/storage/prism/Variable.h
new file mode 100644
index 000000000..248a0e533
--- /dev/null
+++ b/src/storage/prism/Variable.h
@@ -0,0 +1,64 @@
+#ifndef STORM_STORAGE_PRISM_VARIABLE_H_
+#define STORM_STORAGE_PRISM_VARIABLE_H_
+
+#include <map>
+
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace prism {
+        class Variable {
+        public:
+            // Create default implementations of constructors/assignment.
+            Variable(Variable const& otherVariable) = default;
+            Variable& operator=(Variable const& otherVariable)= default;
+            Variable(Variable&& otherVariable) = default;
+            Variable& operator=(Variable&& otherVariable) = default;
+            
+            /*!
+             * Retrieves the name of the variable.
+             *
+             * @return The name of the variable.
+             */
+            std::string const& getName() const;
+            
+            /*!
+             * Retrieves the expression defining the initial value of the variable.
+             *
+             * @return The expression defining the initial value of the variable.
+             */
+            storm::expressions::Expression const& getInitialValueExpression() const;
+                        
+            // Make the constructors protected to forbid instantiation of this class.
+        protected:
+            Variable() = default;
+            
+            /*!
+             * Creates a variable with the given name and initial value.
+             *
+             * @param variableName The name of the variable.
+             * @param initialValueExpression The constant expression that defines the initial value of the variable.
+             */
+            Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression);
+            
+            /*!
+             * Creates a copy of the given variable and performs the provided renaming.
+             *
+             * @param oldVariable The variable to copy.
+             * @param newName New name of this variable.
+             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             */
+            Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming);
+            
+        private:
+            // The name of the variable.
+            std::string variableName;
+            
+            // The constant expression defining the initial value of the variable.
+            storm::expressions::Expression initialValueExpression;
+        };
+        
+    } // namespace prism
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_VARIABLE_H_ */
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 959bc5db0..9230f00e3 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -6,8 +6,8 @@
 #include "src/storage/dd/DdMetaVariable.h"
 
 TEST(CuddDdManager, Constants) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
-    storm::dd::Dd<storm::dd::CUDD> zero;
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
+    storm::dd::Dd<storm::dd::DdType::CUDD> zero;
     ASSERT_NO_THROW(zero = manager->getZero());
     
     EXPECT_EQ(0, zero.getNonZeroCount());
@@ -16,7 +16,7 @@ TEST(CuddDdManager, Constants) {
     EXPECT_EQ(0, zero.getMin());
     EXPECT_EQ(0, zero.getMax());
     
-    storm::dd::Dd<storm::dd::CUDD> one;
+    storm::dd::Dd<storm::dd::DdType::CUDD> one;
     ASSERT_NO_THROW(one = manager->getOne());
     
     EXPECT_EQ(1, one.getNonZeroCount());
@@ -25,7 +25,7 @@ TEST(CuddDdManager, Constants) {
     EXPECT_EQ(1, one.getMin());
     EXPECT_EQ(1, one.getMax());
 
-    storm::dd::Dd<storm::dd::CUDD> two;
+    storm::dd::Dd<storm::dd::DdType::CUDD> two;
     ASSERT_NO_THROW(two = manager->getConstant(2));
     
     EXPECT_EQ(1, two.getNonZeroCount());
@@ -36,7 +36,7 @@ TEST(CuddDdManager, Constants) {
 }
 
 TEST(CuddDdManager, AddGetMetaVariableTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
     EXPECT_EQ(1, manager->getNumberOfMetaVariables());
     
@@ -56,15 +56,15 @@ TEST(CuddDdManager, AddGetMetaVariableTest) {
     std::set<std::string> metaVariableSet = {"x", "y", "y'"};
     EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames());
     
-    ASSERT_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x'"), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
+    ASSERT_THROW(storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x'"), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
 }
 
 TEST(CuddDdManager, EncodingTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariable("x", 1, 9);
     
-    storm::dd::Dd<storm::dd::CUDD> encoding;
+    storm::dd::Dd<storm::dd::DdType::CUDD> encoding;
     ASSERT_THROW(encoding = manager->getEncoding("x", 0), storm::exceptions::InvalidArgumentException);
     ASSERT_THROW(encoding = manager->getEncoding("x", 10), storm::exceptions::InvalidArgumentException);
     ASSERT_NO_THROW(encoding = manager->getEncoding("x", 4));
@@ -74,10 +74,10 @@ TEST(CuddDdManager, EncodingTest) {
 }
 
 TEST(CuddDdManager, RangeTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
     
-    storm::dd::Dd<storm::dd::CUDD> range;
+    storm::dd::Dd<storm::dd::DdType::CUDD> range;
     ASSERT_THROW(range = manager->getRange("y"), storm::exceptions::InvalidArgumentException);
     ASSERT_NO_THROW(range = manager->getRange("x"));
     
@@ -87,10 +87,10 @@ TEST(CuddDdManager, RangeTest) {
 }
 
 TEST(CuddDdManager, IdentityTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariable("x", 1, 9);
     
-    storm::dd::Dd<storm::dd::CUDD> range;
+    storm::dd::Dd<storm::dd::DdType::CUDD> range;
     ASSERT_THROW(range = manager->getIdentity("y"), storm::exceptions::InvalidArgumentException);
     ASSERT_NO_THROW(range = manager->getIdentity("x"));
     
@@ -100,11 +100,11 @@ TEST(CuddDdManager, IdentityTest) {
 }
 
 TEST(CuddDdMetaVariable, AccessorTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariable("x", 1, 9);
     EXPECT_EQ(1, manager->getNumberOfMetaVariables());
-    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
-    storm::dd::DdMetaVariable<storm::dd::CUDD> const& metaVariableX = manager->getMetaVariable("x");
+    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
+    storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x");
     
     EXPECT_EQ(1, metaVariableX.getLow());
     EXPECT_EQ(9, metaVariableX.getHigh());
@@ -114,14 +114,14 @@ TEST(CuddDdMetaVariable, AccessorTest) {
 }
 
 TEST(CuddDd, OperatorTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariable("x", 1, 9);
     EXPECT_TRUE(manager->getZero() == manager->getZero());
     EXPECT_FALSE(manager->getZero() == manager->getOne());
     
-    storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getOne();
-    storm::dd::Dd<storm::dd::CUDD> dd2 = manager->getOne();
-    storm::dd::Dd<storm::dd::CUDD> dd3 = dd1 + dd2;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne();
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getOne();
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd3 = dd1 + dd2;
     EXPECT_TRUE(dd3 == manager->getConstant(2));
     
     dd3 += manager->getZero();
@@ -154,7 +154,7 @@ TEST(CuddDd, OperatorTest) {
     dd3 = dd1.equals(dd2);
     EXPECT_EQ(1, dd3.getNonZeroCount());
     
-    storm::dd::Dd<storm::dd::CUDD> dd4 = dd1.notEquals(dd2);
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd4 = dd1.notEquals(dd2);
     EXPECT_TRUE(dd4 == ~dd3);
     
     dd3 = dd1.less(dd2);
@@ -171,11 +171,11 @@ TEST(CuddDd, OperatorTest) {
 }
 
 TEST(CuddDd, AbstractionTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
-    storm::dd::Dd<storm::dd::CUDD> dd1;
-    storm::dd::Dd<storm::dd::CUDD> dd2;
-    storm::dd::Dd<storm::dd::CUDD> dd3;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
     
     dd1 = manager->getIdentity("x");
     dd2 = manager->getConstant(5);
@@ -216,12 +216,12 @@ TEST(CuddDd, AbstractionTest) {
 }
 
 TEST(CuddDd, SwapTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     
     manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
     manager->addMetaVariable("z", 2, 8);
-    storm::dd::Dd<storm::dd::CUDD> dd1;
-    storm::dd::Dd<storm::dd::CUDD> dd2;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
     
     dd1 = manager->getIdentity("x");
     ASSERT_THROW(dd1.swapVariables({std::make_pair("x", "z")}), storm::exceptions::InvalidArgumentException);
@@ -230,12 +230,12 @@ TEST(CuddDd, SwapTest) {
 }
 
 TEST(CuddDd, MultiplyMatrixTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
     
-    storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getIdentity("x").equals(manager->getIdentity("x'"));
-    storm::dd::Dd<storm::dd::CUDD> dd2 = manager->getRange("x'");
-    storm::dd::Dd<storm::dd::CUDD> dd3;
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getIdentity("x").equals(manager->getIdentity("x'"));
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getRange("x'");
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
     dd1 *= manager->getConstant(2);
     
     ASSERT_NO_THROW(dd3 = dd1.multiplyMatrix(dd2, {"x'"}));
@@ -244,10 +244,10 @@ TEST(CuddDd, MultiplyMatrixTest) {
 }
 
 TEST(CuddDd, GetSetValueTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::CUDD>> manager(new storm::dd::DdManager<storm::dd::CUDD>());
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariable("x", 1, 9);
     
-    storm::dd::Dd<storm::dd::CUDD> dd1 = manager->getOne();
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne();
     ASSERT_NO_THROW(dd1.setValue("x", 4, 2));
     EXPECT_EQ(2, dd1.getLeafCount());
     dd1.exportToDot("dd1.dot");

From 0110758e3e30217e968600dae9a724bb3c7f17f1 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 6 Apr 2014 20:33:34 +0200
Subject: [PATCH 059/147] Further work on adapting classes that store a PRISM
 program to the new expressions. Commit to switch workplace.

Former-commit-id: 00c1b1324d4e9b2f18557e632e3d4e4d76a7c6f6
---
 src/storage/prism/Command.cpp | 80 +++++++++--------------------------
 src/storage/prism/Command.h   | 80 +++++++++++------------------------
 2 files changed, 45 insertions(+), 115 deletions(-)

diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index dbb1eef64..5624eafdb 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -1,75 +1,39 @@
-/*
- * Command.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-#include <iostream>
-
 #include "Command.h"
-#include "src/parser/prismparser/VariableState.h"
 
 namespace storm {
-    namespace ir {
-        
-        Command::Command() : actionName(), guardExpression(), updates(), globalIndex() {
-            // Nothing to do here.
-        }
-        
-        Command::Command(uint_fast64_t globalIndex, std::string const& actionName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& guardExpression, std::vector<storm::ir::Update> const& updates)
-        : actionName(actionName), guardExpression(std::move(guardExpression)), updates(updates), globalIndex(globalIndex) {
+    namespace prism {
+        Command::Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates) : actionName(actionName), guardExpression(guardExpression), updates(updates), globalIndex(globalIndex) {
             // Nothing to do here.
         }
         
-        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState)
-        : actionName(oldCommand.getActionName()), guardExpression(oldCommand.guardExpression->clone(renaming, variableState)), globalIndex(newGlobalIndex) {
-            auto renamingPair = renaming.find(this->actionName);
-            if (renamingPair != renaming.end()) {
-                this->actionName = renamingPair->second;
+        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming) : actionName(oldCommand.getActionName()), guardExpression(oldCommand.getGuardExpression().substitute<std::map>(renaming)), globalIndex(newGlobalIndex) {
+            auto const& namePair = renaming.find(this->actionName);
+            if (namePair != renaming.end()) {
+                this->actionName = namePair->second;
             }
             this->updates.reserve(oldCommand.getNumberOfUpdates());
-            for (Update const& update : oldCommand.updates) {
-                this->updates.emplace_back(update, variableState.getNextGlobalUpdateIndex(), renaming, variableState);
-                variableState.nextGlobalUpdateIndex++;
+            for (Update const& update : oldCommand.getUpdates()) {
+                this->updates.emplace_back(update, update.getGlobalIndex(), renaming);
             }
         }
-        
-        Command::Command(Command const& otherCommand) : actionName(otherCommand.actionName), guardExpression(), updates(otherCommand.updates), globalIndex(otherCommand.globalIndex) {
-            if (otherCommand.guardExpression != nullptr) {
-                guardExpression = otherCommand.guardExpression->clone();
-            }
-        }
-        
-        Command& Command::operator=(Command const& otherCommand) {
-            if (this != &otherCommand) {
-                this->actionName = otherCommand.actionName;
-                this->guardExpression = otherCommand.guardExpression->clone();
-                this->updates = otherCommand.updates;
-                this->globalIndex = otherCommand.globalIndex;
-            }
-            
-            return *this;
-        }
-        
+
         std::string const& Command::getActionName() const {
             return this->actionName;
         }
         
-        std::unique_ptr<storm::ir::expressions::BaseExpression> const& Command::getGuard() const {
+        storm::expressions::Expression const& Command::getGuardExpression() const {
             return guardExpression;
         }
         
-        uint_fast64_t Command::getNumberOfUpdates() const {
+        std::size_t Command::getNumberOfUpdates() const {
             return this->updates.size();
         }
         
-        storm::ir::Update const& Command::getUpdate(uint_fast64_t index) const {
+        storm::prism::Update const& Command::getUpdate(uint_fast64_t index) const {
             return this->updates[index];
         }
         
-        std::vector<storm::ir::Update> const& Command::getUpdates() const {
+        std::vector<storm::prism::Update> const& Command::getUpdates() const {
             return this->updates;
         }
         
@@ -77,18 +41,16 @@ namespace storm {
             return this->globalIndex;
         }
         
-        std::string Command::toString() const {
-            std::stringstream result;
-            result << "[" << actionName << "] " << guardExpression->toString() << " -> ";
-            for (uint_fast64_t i = 0; i < updates.size(); ++i) {
-                result << updates[i].toString();
-                if (i < updates.size() - 1) {
-                    result << " + ";
+        std::ostream& operator<<(std::ostream& stream, Command const& command) {
+            stream << "[" << command.getActionName() << "] " << command.getGuardExpression() << " -> ";
+            for (uint_fast64_t i = 0; i < command.getUpdates().size(); ++i) {
+                stream << command.getUpdate(i);
+                if (i < command.getUpdates().size() - 1) {
+                    stream << " + ";
                 }
             }
-            result << ";";
-            return result.str();
+            stream << ";";
+            return stream;
         }
-        
     } // namespace ir
 } // namespace storm
diff --git a/src/storage/prism/Command.h b/src/storage/prism/Command.h
index 04efe8b86..8cb905346 100644
--- a/src/storage/prism/Command.h
+++ b/src/storage/prism/Command.h
@@ -1,69 +1,42 @@
-/*
- * Command.h
- *
- *  Created on: 06.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_COMMAND_H_
-#define STORM_IR_COMMAND_H_
+#ifndef STORM_STORAGE_PRISM_COMMAND_H_
+#define STORM_STORAGE_PRISM_COMMAND_H_
 
 #include <vector>
 #include <string>
 #include <map>
 
-#include "expressions/BaseExpression.h"
-#include "Update.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/prism/Update.h"
 
 namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing a command.
-         */
+    namespace prism {
         class Command {
         public:
             /*!
-             * Default constructor. Creates a a command without name, guard and updates.
-             */
-            Command();
-            
-            /*!
-             * Creates a command with the given name, guard and updates.
+             * Creates a command with the given action name, guard and updates.
              *
              * @param globalIndex The global index of the command.
              * @param actionName The action name of the command.
              * @param guardExpression the expression that defines the guard of the command.
              * @param updates A list of updates that is associated with this command.
              */
-            Command(uint_fast64_t globalIndex, std::string const& actionName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& guardExpression, std::vector<storm::ir::Update> const& updates);
+            Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates);
             
             /*!
              * Creates a copy of the given command and performs the provided renaming.
              *
              * @param oldCommand The command to copy.
              * @param newGlobalIndex The global index of the copy of the command.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param variableState An object knowing about the variables in the system.
-             */
-            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState);
-            
-            /*!
-             * Performs a deep-copy of the given command.
-             *
-             * @param otherCommand The command to copy.
+             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
              */
-            Command(Command const& otherCommand);
+            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming);
             
-            Command& operator=(Command const& otherCommand);
+            // Create default implementations of constructors/assignment.
+            Command() = default;
+            Command(Command const& otherVariable) = default;
+            Command& operator=(Command const& otherVariable)= default;
+            Command(Command&& otherVariable) = default;
+            Command& operator=(Command&& otherVariable) = default;
             
             /*!
              * Retrieves the action name of this command.
@@ -77,28 +50,28 @@ namespace storm {
              *
              * @return A reference to the guard of the command.
              */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> const& getGuard() const;
+            storm::expressions::Expression const& getGuardExpression() const;
             
             /*!
              * Retrieves the number of updates associated with this command.
              *
              * @return The number of updates associated with this command.
              */
-            uint_fast64_t getNumberOfUpdates() const;
+            std::size_t getNumberOfUpdates() const;
             
             /*!
              * Retrieves a reference to the update with the given index.
              *
              * @return A reference to the update with the given index.
              */
-            storm::ir::Update const& getUpdate(uint_fast64_t index) const;
+            storm::prism::Update const& getUpdate(uint_fast64_t index) const;
             
             /*!
              * Retrieves a vector of all updates associated with this command.
              *
              * @return A vector of updates associated with this command.
              */
-            std::vector<storm::ir::Update> const& getUpdates() const;
+            std::vector<storm::prism::Update> const& getUpdates() const;
             
             /*!
              * Retrieves the global index of the command, that is, a unique index over all modules.
@@ -107,28 +80,23 @@ namespace storm {
              */
             uint_fast64_t getGlobalIndex() const;
             
-            /*!
-             * Retrieves a string representation of this command.
-             *
-             * @return A string representation of this command.
-             */
-            std::string toString() const;
+            friend std::ostream& operator<<(std::ostream& stream, Command const& command);
             
         private:
             // The name of the command.
             std::string actionName;
             
             // The expression that defines the guard of the command.
-            std::unique_ptr<storm::ir::expressions::BaseExpression> guardExpression;
+            storm::expressions::Expression guardExpression;
             
             // The list of updates of the command.
-            std::vector<storm::ir::Update> updates;
+            std::vector<storm::prism::Update> updates;
             
             // The global index of the command.
             uint_fast64_t globalIndex;
         };
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_COMMAND_H_ */
+#endif /* STORM_STORAGE_PRISM_COMMAND_H_ */

From 5407978e8e9d31ece2e03af4dec29b3fb0595b3e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 7 Apr 2014 17:12:49 +0200
Subject: [PATCH 060/147] Minor update: PRISM variables now store whether an
 initial value for them was given explicitly in the program.

Former-commit-id: 6672539447630f05052ee073cfd2ccdee767ed5a
---
 src/storage/prism/BooleanVariable.cpp |  4 ++--
 src/storage/prism/IntegerVariable.cpp |  6 +++---
 src/storage/prism/Variable.cpp        |  8 ++++++--
 src/storage/prism/Variable.h          | 16 ++++++++++++++--
 4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
index adf12b165..39ea86304 100644
--- a/src/storage/prism/BooleanVariable.cpp
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -2,11 +2,11 @@
 
 namespace storm {
     namespace prism {
-        BooleanVariable::BooleanVariable(std::string const& variableName) : BooleanVariable(variableName, storm::expressions::Expression::createFalse()) {
+        BooleanVariable::BooleanVariable(std::string const& variableName) : Variable(variableName, storm::expressions::Expression::createFalse(), true) {
             // Nothing to do here.
         }
 
-        BooleanVariable::BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression) {
+        BooleanVariable::BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression, false) {
             // Nothing to do here.
         }
         
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index 7f11a8bc2..10a3f3e88 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -2,11 +2,11 @@
 
 namespace storm {
     namespace prism {
-        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression) : IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, lowerBoundExpression) {
+        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression) : Variable(variableName, lowerBoundExpression, true), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
             // Intentionally left empty.
         }
 
-        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
+        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression, false), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
             // Intentionally left empty.
         }
         
@@ -23,7 +23,7 @@ namespace storm {
         }
         
         std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable) {
-            stream << this->getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << variable.getInitialValueExpression() << ";";
+            stream << variable.getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << variable.getInitialValueExpression() << ";";
             return stream;
         }
     } // namespace prism
diff --git a/src/storage/prism/Variable.cpp b/src/storage/prism/Variable.cpp
index 9527e7f76..a6f6f57ae 100644
--- a/src/storage/prism/Variable.cpp
+++ b/src/storage/prism/Variable.cpp
@@ -4,11 +4,11 @@
 
 namespace storm {
     namespace prism {
-        Variable::Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression) : variableName(variableName), initialValueExpression(initialValueExpression) {
+        Variable::Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue) : variableName(variableName), initialValueExpression(initialValueExpression), defaultInitialValue(defaultInitialValue) {
             // Nothing to do here.
         }
         
-        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : variableName(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)) {
+        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : variableName(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
             // Intentionally left empty.
         }
         
@@ -16,6 +16,10 @@ namespace storm {
             return variableName;
         }
         
+        bool Variable::hasDefaultInitialValue() const {
+            return this->defaultInitialValue;
+        }
+
         storm::expressions::Expression const& Variable::getInitialValueExpression() const {
             return this->initialValueExpression;
         }
diff --git a/src/storage/prism/Variable.h b/src/storage/prism/Variable.h
index 248a0e533..ef77a2c2d 100644
--- a/src/storage/prism/Variable.h
+++ b/src/storage/prism/Variable.h
@@ -28,7 +28,14 @@ namespace storm {
              * @return The expression defining the initial value of the variable.
              */
             storm::expressions::Expression const& getInitialValueExpression() const;
-                        
+            
+            /*!
+             * Retrieves whether the variable has the default initial value with respect to its type.
+             *
+             * @return True iff the variable has the default initial value.
+             */
+            bool hasDefaultInitialValue() const;
+            
             // Make the constructors protected to forbid instantiation of this class.
         protected:
             Variable() = default;
@@ -38,8 +45,10 @@ namespace storm {
              *
              * @param variableName The name of the variable.
              * @param initialValueExpression The constant expression that defines the initial value of the variable.
+             * @param hasDefaultInitialValue A flag indicating whether the initial value of the variable is its default
+             * value.
              */
-            Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression);
+            Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue);
             
             /*!
              * Creates a copy of the given variable and performs the provided renaming.
@@ -56,6 +65,9 @@ namespace storm {
             
             // The constant expression defining the initial value of the variable.
             storm::expressions::Expression initialValueExpression;
+            
+            // A flag that stores whether the variable has its default initial expression.
+            bool defaultInitialValue;
         };
         
     } // namespace prism

From d88876d0cd744a464d0ecebebc86500df48b5211 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 7 Apr 2014 20:15:28 +0200
Subject: [PATCH 061/147] PRISM classes almost adapted to new expression
 classes. TODO: source file of PRISM program.

Former-commit-id: 929a78684d5d17268ccb28f683eedb8397e8e2c3
---
 src/storage/prism/Module.cpp           | 189 +++++++++----------------
 src/storage/prism/Module.h             | 160 ++++++++-------------
 src/storage/prism/Program.h            | 175 ++++++++++++++---------
 src/storage/prism/RewardModel.cpp      |  51 +++----
 src/storage/prism/RewardModel.h        |  73 +++++-----
 src/storage/prism/StateReward.cpp      |  38 ++---
 src/storage/prism/StateReward.h        |  76 +++-------
 src/storage/prism/TransitionReward.cpp |  41 ++----
 src/storage/prism/TransitionReward.h   | 151 ++++++++------------
 9 files changed, 387 insertions(+), 567 deletions(-)

diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 5724db8df..6da269889 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -1,177 +1,100 @@
-/*
- * Module.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-#include <iostream>
-#include "utility/OsDetection.h"
-
-#include "Module.h"
-#include "src/parser/prismparser/VariableState.h"
+#include "src/storage/prism/Module.h"
+#include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/OutOfRangeException.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
 namespace storm {
-    namespace ir {
-        
-        Module::Module() : moduleName(), booleanVariables(), integerVariables(), booleanVariableToLocalIndexMap(),
-        integerVariableToLocalIndexMap(), commands(), actions(), actionsToCommandIndexMap() {
-            // Nothing to do here.
-        }
-        
-        Module::Module(std::string const& moduleName,
-                       std::vector<storm::ir::BooleanVariable> const& booleanVariables,
-                       std::vector<storm::ir::IntegerVariable> const& integerVariables,
-                       std::map<std::string, uint_fast64_t> const& booleanVariableToLocalIndexMap,
-                       std::map<std::string, uint_fast64_t> const& integerVariableToLocalIndexMap,
-                       std::vector<storm::ir::Command> const& commands)
-        : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables),
-        booleanVariableToLocalIndexMap(booleanVariableToLocalIndexMap),
-        integerVariableToLocalIndexMap(integerVariableToLocalIndexMap), commands(commands), actions(), actionsToCommandIndexMap() {
+    namespace prism {
+        Module::Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands), actions(), actionsToCommandIndexMap() {
             // Initialize the internal mappings for fast information retrieval.
             this->collectActions();
         }
         
-        Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState)
-        : moduleName(newModuleName), booleanVariableToLocalIndexMap(oldModule.booleanVariableToLocalIndexMap), integerVariableToLocalIndexMap(oldModule.integerVariableToLocalIndexMap) {
-            LOG4CPLUS_TRACE(logger, "Start renaming " << oldModule.getName() << " to " << moduleName << ".");
-            
-            // Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception
-            // is thrown.
-            this->booleanVariables.reserve(oldModule.getNumberOfBooleanVariables());
-            for (BooleanVariable const& booleanVariable : oldModule.booleanVariables) {
-                auto renamingPair = renaming.find(booleanVariable.getName());
-                if (renamingPair == renaming.end()) {
-                    LOG4CPLUS_ERROR(logger, "Boolean variable " << moduleName << "." << booleanVariable.getName() << " was not renamed.");
-                    throw storm::exceptions::InvalidArgumentException() << "Boolean variable " << moduleName << "." << booleanVariable.getName() << " was not renamed.";
-                } else {
-                    uint_fast64_t globalIndex = variableState.addBooleanVariable(renamingPair->second);
-                    this->booleanVariables.emplace_back(booleanVariable, renamingPair->second, globalIndex, renaming, variableState);
-                }
+        Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming) : moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
+            // Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception is thrown.
+            for (auto const& nameVariablePair : oldModule.getBooleanVariables()) {
+                auto renamingPair = renaming.find(nameVariablePair.first);
+                LOG_THROW(renamingPair == renaming.end(), storm::exceptions::InvalidArgumentException, "Boolean variable " << moduleName << "." << nameVariablePair.first << " was not renamed.");
+                this->booleanVariables.emplace(nameVariablePair.first, BooleanVariable(nameVariablePair.second, renamingPair->second, renaming));
             }
+            
             // Now do the same for the integer variables.
-            this->integerVariables.reserve(oldModule.getNumberOfIntegerVariables());
-            for (IntegerVariable const& integerVariable : oldModule.integerVariables) {
-                auto renamingPair = renaming.find(integerVariable.getName());
-                if (renamingPair == renaming.end()) {
-                    LOG4CPLUS_ERROR(logger, "Integer variable " << moduleName << "." << integerVariable.getName() << " was not renamed.");
-                    throw storm::exceptions::InvalidArgumentException() << "Integer variable " << moduleName << "." << integerVariable.getName() << " was not renamed.";
-                } else {
-                    uint_fast64_t globalIndex = variableState.addIntegerVariable(renamingPair->second);
-                    this->integerVariables.emplace_back(integerVariable, renamingPair->second, globalIndex, renaming, variableState);
-                }
+            for (auto const& nameVariablePair : oldModule.getIntegerVariables()) {
+                auto renamingPair = renaming.find(nameVariablePair.first);
+                LOG_THROW(renamingPair == renaming.end(), storm::exceptions::InvalidArgumentException, "Integer variable " << moduleName << "." << nameVariablePair.first << " was not renamed.");
+                this->integerVariables.emplace(nameVariablePair.first, IntegerVariable(nameVariablePair.second, renamingPair->second, renaming));
             }
             
             // Now we are ready to clone all commands and rename them if requested.
             this->commands.reserve(oldModule.getNumberOfCommands());
-            for (Command const& command : oldModule.commands) {
-                this->commands.emplace_back(command, variableState.getNextGlobalCommandIndex(), renaming, variableState);
-                variableState.nextGlobalCommandIndex++;
+            for (Command const& command : oldModule.getCommands()) {
+                this->commands.emplace_back(command, command.getGlobalIndex(), renaming);
             }
-            this->collectActions();
             
-            LOG4CPLUS_TRACE(logger, "Finished renaming...");
+            // Finally, update internal mapping.
+            this->collectActions();
         }
         
-        uint_fast64_t Module::getNumberOfBooleanVariables() const {
+        std::size_t Module::getNumberOfBooleanVariables() const {
             return this->booleanVariables.size();
         }
         
-        storm::ir::BooleanVariable const& Module::getBooleanVariable(uint_fast64_t index) const {
-            return this->booleanVariables[index];
+        std::size_t Module::getNumberOfIntegerVariables() const {
+            return this->integerVariables.size();
         }
         
-        storm::ir::BooleanVariable const& Module::getBooleanVariable(std::string const& variableName) const {
-            uint_fast64_t index = this->getBooleanVariableIndex(variableName);
-            return this->booleanVariables[index];
+        storm::prism::BooleanVariable const& Module::getBooleanVariable(std::string const& variableName) const {
+            auto const& nameVariablePair = this->getBooleanVariables().find(variableName);
+            LOG_THROW(nameVariablePair == this->getBooleanVariables().end(), storm::exceptions::InvalidArgumentException, "Unknown boolean variable '" << variableName << "'.");
+            return nameVariablePair->second;
         }
         
-        uint_fast64_t Module::getNumberOfIntegerVariables() const {
-            return this->integerVariables.size();
+        std::map<std::string, storm::prism::BooleanVariable> const& Module::getBooleanVariables() const {
+            return this->booleanVariables;
         }
-        
-        storm::ir::IntegerVariable const& Module::getIntegerVariable(uint_fast64_t index) const {
-            return this->integerVariables[index];
+
+        storm::prism::IntegerVariable const& Module::getIntegerVariable(std::string const& variableName) const {
+            auto const& nameVariablePair = this->getIntegerVariables().find(variableName);
+            LOG_THROW(nameVariablePair == this->getIntegerVariables().end(), storm::exceptions::InvalidArgumentException, "Unknown integer variable '" << variableName << "'.");
+            return nameVariablePair->second;
         }
         
-        storm::ir::IntegerVariable const& Module::getIntegerVariable(std::string const& variableName) const {
-            uint_fast64_t index = this->getIntegerVariableIndex(variableName);
-            return this->integerVariables[index];
+        std::map<std::string, storm::prism::IntegerVariable> const& Module::getIntegerVariables() const {
+            return this->integerVariables;
         }
         
-        uint_fast64_t Module::getNumberOfCommands() const {
+        std::size_t Module::getNumberOfCommands() const {
             return this->commands.size();
         }
         
-        uint_fast64_t Module::getBooleanVariableIndex(std::string const& variableName) const {
-            auto it = booleanVariableToLocalIndexMap.find(variableName);
-            if (it != booleanVariableToLocalIndexMap.end()) {
-                return it->second;
-            }
-            LOG4CPLUS_ERROR(logger, "Cannot retrieve index of unknown boolean variable " << variableName << ".");
-            throw storm::exceptions::InvalidArgumentException() << "Cannot retrieve index of unknown boolean variable " << variableName << ".";
-        }
-        
-        uint_fast64_t Module::getIntegerVariableIndex(std::string const& variableName) const {
-            auto it = integerVariableToLocalIndexMap.find(variableName);
-            if (it != integerVariableToLocalIndexMap.end()) {
-                return it->second;
-            }
-            LOG4CPLUS_ERROR(logger, "Cannot retrieve index of unknown integer variable " << variableName << ".");
-            throw storm::exceptions::InvalidArgumentException() << "Cannot retrieve index of unknown integer variable " << variableName << ".";
+        storm::prism::Command const& Module::getCommand(uint_fast64_t index) const {
+            return this->commands[index];
         }
         
-        storm::ir::Command const& Module::getCommand(uint_fast64_t index) const {
-            return this->commands[index];
+        std::vector<storm::prism::Command> const& Module::getCommands() const {
+            return this->commands;
         }
         
         std::string const& Module::getName() const {
             return this->moduleName;
         }
         
-        std::string Module::toString() const {
-            std::stringstream result;
-            result << "module " << moduleName << std::endl;
-            for (auto variable : booleanVariables) {
-                result << "\t" << variable.toString() << std::endl;
-            }
-            for (auto variable : integerVariables) {
-                result << "\t" << variable.toString() << std::endl;
-            }
-            for (auto command : commands) {
-                result << "\t" << command.toString() << std::endl;
-            }
-            result << "endmodule" << std::endl;
-            return result.str();
-        }
-        
         std::set<std::string> const& Module::getActions() const {
             return this->actions;
         }
         
         bool Module::hasAction(std::string const& action) const {
             auto const& actionEntry = this->actions.find(action);
-            if (actionEntry != this->actions.end()) {
-                return true;
-            }
-            return false;
+            return actionEntry != this->actions.end();
         }
         
-        std::set<uint_fast64_t> const& Module::getCommandsByAction(std::string const& action) const {
+        std::set<uint_fast64_t> const& Module::getCommandIndicesByAction(std::string const& action) const {
             auto actionsCommandSetPair = this->actionsToCommandIndexMap.find(action);
             if (actionsCommandSetPair != this->actionsToCommandIndexMap.end()) {
                 return actionsCommandSetPair->second;
             }
             
-            LOG4CPLUS_ERROR(logger, "Action name '" << action << "' does not exist in module.");
-            throw storm::exceptions::OutOfRangeException() << "Action name '" << action << "' does not exist in module.";
+            LOG_THROW(false, storm::exceptions::OutOfRangeException, "Action name '" << action << "' does not exist in module.");
         }
         
         void Module::collectActions() {
@@ -199,19 +122,33 @@ namespace storm {
             }
         }
         
-        void Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
+        Module Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
             // First construct the new vector of commands.
-            std::vector<storm::ir::Command> newCommands;
+            std::vector<storm::prism::Command> newCommands;
             for (auto const& command : commands) {
                 if (indexSet.find(command.getGlobalIndex()) != indexSet.end()) {
-                    newCommands.push_back(std::move(command));
+                    newCommands.push_back(command);
                 }
             }
-            commands = std::move(newCommands);
             
-            // Then refresh the internal mappings.
-            this->collectActions();
+            return Module(this->getName(), this->getBooleanVariables(), this->getIntegerVariables(), newCommands);
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, Module const& module) {
+            stream << "module " << module.getName() << std::endl;
+            for (auto const& nameVariablePair : module.getBooleanVariables()) {
+                stream << "\t" << nameVariablePair.second << std::endl;
+            }
+            for (auto const& nameVariablePair : module.getIntegerVariables()) {
+                stream << "\t" << nameVariablePair.second << std::endl;
+            }
+            for (auto const& command : module.getCommands()) {
+                stream << "\t" << command << std::endl;
+            }
+            stream << "endmodule" << std::endl;
+            return stream;
         }
+
         
     } // namespace ir
 } // namespace storm
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index d9570c652..595a48c5c 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -1,149 +1,115 @@
-/*
- * Module.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_MODULE_H_
-#define STORM_IR_MODULE_H_
-
-#include "utility/OsDetection.h"
-#include <boost/container/flat_set.hpp>
-
-#ifdef LINUX
-#include <boost/container/map.hpp>
-#endif
-#include <map>
+#ifndef STORM_STORAGE_PRISM_MODULE_H_
+#define STORM_STORAGE_PRISM_MODULE_H_
 
 #include <set>
 #include <string>
 #include <vector>
 #include <memory>
+#include <boost/container/flat_set.hpp>
 
-#include "BooleanVariable.h"
-#include "IntegerVariable.h"
-#include "Command.h"
-#include "expressions/VariableExpression.h"
+#include "src/storage/prism/BooleanVariable.h"
+#include "src/storage/prism/IntegerVariable.h"
+#include "src/storage/prism/Command.h"
+#include "src/storage/expressions/VariableExpression.h"
 
 namespace storm {
-    
-    namespace parser {
-        namespace prism {
-            class VariableState;
-        } // namespace prismparser
-    } // namespace parser
-    
-    namespace ir {
-        
-        /*!
-         * A class representing a module.
-         */
+    namespace prism {
         class Module {
         public:
-            /*!
-             * Default constructor. Creates an empty module.
-             */
-            Module();
-            
             /*!
              * Creates a module with the given name, variables and commands.
              *
              * @param moduleName The name of the module.
              * @param booleanVariables The boolean variables defined by the module.
              * @param integerVariables The integer variables defined by the module.
-             * @param booleanVariableToLocalIndexMap A mapping of boolean variables to local (i.e. module-local) indices.
-             * @param integerVariableToLocalIndexMap A mapping of integer variables to local (i.e. module-local) indices.
              * @param commands The commands of the module.
              */
-            Module(std::string const& moduleName, std::vector<storm::ir::BooleanVariable> const& booleanVariables,
-                   std::vector<storm::ir::IntegerVariable> const& integerVariables,
-                   std::map<std::string, uint_fast64_t> const& booleanVariableToLocalIndexMap,
-                   std::map<std::string, uint_fast64_t> const& integerVariableToLocalIndexMap,
-                   std::vector<storm::ir::Command> const& commands);
+            Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables,
+                   std::map<std::string, storm::prism::IntegerVariable> const& integerVariables,
+                   std::vector<storm::prism::Command> const& commands);
             
             /*!
-             * Special copy constructor, implementing the module renaming functionality.
-             * This will create a new module having all identifiers renamed according to the given map.
+             * Special copy constructor, implementing the module renaming functionality. This will create a new module
+             * having all identifiers renamed according to the given map.
              *
              * @param oldModule The module to be copied.
              * @param newModuleName The name of the new module.
              * @param renaming A mapping of identifiers to the new identifiers they are to be replaced with.
-             * @param variableState An object knowing about the variables in the system.
              */
-            Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState);
+            Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming);
+            
+            // Create default implementations of constructors/assignment.
+            Module() = default;
+            Module(Module const& otherVariable) = default;
+            Module& operator=(Module const& otherVariable)= default;
+            Module(Module&& otherVariable) = default;
+            Module& operator=(Module&& otherVariable) = default;
             
             /*!
              * Retrieves the number of boolean variables in the module.
              *
              * @return the number of boolean variables in the module.
              */
-            uint_fast64_t getNumberOfBooleanVariables() const;
+            std::size_t getNumberOfBooleanVariables() const;
             
             /*!
-             * Retrieves a reference to the boolean variable with the given index.
+             * Retrieves the number of integer variables in the module.
              *
-             * @return A reference to the boolean variable with the given index.
+             * @return The number of integer variables in the module.
              */
-            storm::ir::BooleanVariable const& getBooleanVariable(uint_fast64_t index) const;
+            std::size_t getNumberOfIntegerVariables() const;
             
             /*!
              * Retrieves a reference to the boolean variable with the given name.
              *
+             * @param variableName The name of the boolean variable to retrieve.
              * @return A reference to the boolean variable with the given name.
              */
-            storm::ir::BooleanVariable const& getBooleanVariable(std::string const& variableName) const;
+            storm::prism::BooleanVariable const& getBooleanVariable(std::string const& variableName) const;
             
             /*!
-             * Retrieves the number of integer variables in the module.
+             * Retrieves the boolean variables of the module.
              *
-             * @return The number of integer variables in the module.
+             * @return The boolean variables of the module.
              */
-            uint_fast64_t getNumberOfIntegerVariables() const;
+            std::map<std::string, storm::prism::BooleanVariable> const& getBooleanVariables() const;
             
             /*!
-             * Retrieves a reference to the integer variable with the given index.
+             * Retrieves a reference to the integer variable with the given name.
              *
-             * @return A reference to the integer variable with the given index.
+             * @param variableName The name of the integer variable to retrieve.
+             * @return A reference to the integer variable with the given name.
              */
-            storm::ir::IntegerVariable const& getIntegerVariable(uint_fast64_t index) const;
-            
+            storm::prism::IntegerVariable const& getIntegerVariable(std::string const& variableName) const;
+
             /*!
-             * Retrieves a reference to the boolean variable with the given name.
+             * Retrieves the integer variables of the module.
              *
-             * @return A reference to the boolean variable with the given name.
+             * @return The integer variables of the module.
              */
-            storm::ir::IntegerVariable const& getIntegerVariable(std::string const& variableName) const;
-            
+            std::map<std::string, storm::prism::IntegerVariable> const& getIntegerVariables() const;
+
             /*!
              * Retrieves the number of commands of this module.
              *
              * @return the number of commands of this module.
              */
-            uint_fast64_t getNumberOfCommands() const;
+            std::size_t getNumberOfCommands() const;
             
             /*!
-             * Retrieves the index of the boolean variable with the given name.
+             * Retrieves a reference to the command with the given index.
              *
-             * @param variableName The name of the boolean variable whose index to retrieve.
-             * @return The index of the boolean variable with the given name.
+             * @param index The index of the command to retrieve.
+             * @return A reference to the command with the given index.
              */
-            uint_fast64_t getBooleanVariableIndex(std::string const& variableName) const;
+            storm::prism::Command const& getCommand(uint_fast64_t index) const;
             
             /*!
-             * Retrieves the index of the integer variable with the given name.
+             * Retrieves the commands of the module.
              *
-             * @param variableName The name of the integer variable whose index to retrieve.
-             * @return The index of the integer variable with the given name.
+             * @return The commands of the module.
              */
-            uint_fast64_t getIntegerVariableIndex(std::string const& variableName) const;
-            
-            /*!
-             * Retrieves a reference to the command with the given index.
-             *
-             * @return A reference to the command with the given index.
-             */
-            storm::ir::Command const& getCommand(uint_fast64_t index) const;
+            std::vector<storm::prism::Command> const& getCommands() const;
             
             /*!
              * Retrieves the name of the module.
@@ -152,13 +118,6 @@ namespace storm {
              */
             std::string const& getName() const;
             
-            /*!
-             * Retrieves a string representation of this module.
-             *
-             * @return a string representation of this module.
-             */
-            std::string toString() const;
-            
             /*!
              * Retrieves the set of actions present in this module.
              *
@@ -170,7 +129,7 @@ namespace storm {
              * Retrieves whether or not this module contains a command labeled with the given action.
              *
              * @param action The action name to look for in this module.
-             * @return True if the module has at least one command labeled with the given action.
+             * @return True iff the module has at least one command labeled with the given action.
              */
             bool hasAction(std::string const& action) const;
             
@@ -180,15 +139,18 @@ namespace storm {
              * @param action The action with which the commands have to be labelled.
              * @return A set of indices of commands that are labelled with the given action.
              */
-            std::set<uint_fast64_t> const& getCommandsByAction(std::string const& action) const;
+            std::set<uint_fast64_t> const& getCommandIndicesByAction(std::string const& action) const;
             
             /*!
-             * Deletes all commands with indices not in the given set from the module.
+             * Creates a new module that drops all commands whose indices are not in the given set.
              *
              * @param indexSet The set of indices for which to keep the commands.
+             * @return The module resulting from erasing all commands whose indices are not in the given set.
              */
-            void restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
+            Module restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
             
+            friend std::ostream& operator<<(std::ostream& stream, Module const& module);
+
         private:
             /*!
              * Computes the locally maintained mappings for fast data retrieval.
@@ -199,16 +161,10 @@ namespace storm {
             std::string moduleName;
             
             // A list of boolean variables.
-            std::vector<storm::ir::BooleanVariable> booleanVariables;
+            std::map<std::string, storm::prism::BooleanVariable> booleanVariables;
             
             // A list of integer variables.
-            std::vector<storm::ir::IntegerVariable> integerVariables;
-            
-            // A map of boolean variable names to their index.
-            std::map<std::string, uint_fast64_t> booleanVariableToLocalIndexMap;
-            
-            // A map of integer variable names to their index.
-            std::map<std::string, uint_fast64_t> integerVariableToLocalIndexMap;
+            std::map<std::string, storm::prism::IntegerVariable> integerVariables;
             
             // The commands associated with the module.
             std::vector<storm::ir::Command> commands;
@@ -220,7 +176,7 @@ namespace storm {
             std::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
         };
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_MODULE_H_ */
+#endif /* STORM_STORAGE_PRISM_MODULE_H_ */
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 169a3fe32..172d3f3b5 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -1,66 +1,44 @@
-/*
- * Program.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_PROGRAM_H_
-#define STORM_IR_PROGRAM_H_
+#ifndef STORM_STORAGE_PRISM_PROGRAM_H_
+#define STORM_STORAGE_PRISM_PROGRAM_H_
 
 #include <map>
 #include <vector>
-#include <memory>
 #include <set>
 #include <boost/container/flat_set.hpp>
 
 #include "src/storage/expressions/Expression.h"
-#include "Module.h"
-#include "RewardModel.h"
+#include "src/storage/prism/Module.h"
+#include "src/storage/prism/RewardModel.h"
 
 namespace storm {
-    namespace ir {
-        
-        /*!
-         * A class representing a program.
-         */
+    namespace prism {
         class Program {
         public:
-            
             /*!
              * An enum for the different model types.
              */
-            enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP};
+            enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP, MA};
             
             /*!
-             * Creates a program with the given model type, undefined constants, modules, rewards and labels.
+             * Creates a program with the given model type, undefined constants, global variables, modules, reward
+             * models, labels and initial states.
              *
-             * @param modelType The type of the model that this program gives rise to.
-             * @param booleanUndefinedConstantExpressions A map of undefined boolean constants to their
-             * expression nodes.
-             * @param integerUndefinedConstantExpressions A map of undefined integer constants to their
-             * expression nodes.
-             * @param doubleUndefinedConstantExpressions A map of undefined double constants to their
-             * expression nodes.
-             * @param globalBooleanVariables A list of global boolean variables.
-             * @param globalIntegerVariables A list of global integer variables.
-             * @param globalBooleanVariableToIndexMap A mapping from global boolean variable names to the index in the
-             * list of global boolean variables.
-             * @param globalIntegerVariableToIndexMap A mapping from global integer variable names to the index in the
-             * list of global integer variables.
+             * @param modelType The type of the program.
+             * @param undefinedBooleanConstants The undefined boolean constants of the program.
+             * @param undefinedIntegerConstants The undefined integer constants of the program.
+             * @param undefinedDoubleConstants The undefined double constants of the program.
+             * @param globalBooleanVariables The global boolean variables of the program.
+             * @param globalIntegerVariables The global integer variables of the program.
              * @param modules The modules of the program.
-             * @param rewards The reward models of the program.
-             * @param labels The labels defined for this model.
-             */
-            Program(ModelType modelType,
-                    std::set<std::string> const& booleanUndefinedConstantExpressions,
-                    std::set<std::string> const& integerUndefinedConstantExpressions,
-                    std::set<std::string> const& doubleUndefinedConstantExpressions,
-                    std::map<std::string, BooleanVariable> const& globalBooleanVariables,
-                    std::map<std::string, IntegerVariable> const& globalIntegerVariables,
-                    std::vector<storm::ir::Module> const& modules,
-                    std::map<std::string, storm::ir::RewardModel> const& rewards,
-                    std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels);
+             * @param hasInitialStatesExpression A flag indicating whether the program specifies its initial states via
+             * an explicit initial construct.
+             * @param initialStatesExpression If the model specifies an explicit initial construct, this expression
+             * defines its initial states. Otherwise it is irrelevant and may be set to an arbitrary (but valid)
+             * expression, e.g. false.
+             * @param rewardModels The reward models of the program.
+             * @param labels The labels defined for this program.
+             */
+            Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels);
             
             // Provide default implementations for constructors and assignments.
             Program() = default;
@@ -76,31 +54,82 @@ namespace storm {
              */
             ModelType getModelType() const;
 
+            /*!
+             * Retrieves whether there are undefined constants of any type in the program.
+             *
+             * @return True iff there are undefined constants of any type in the program.
+             */
             bool hasUndefinedConstants() const;
             
+            /*!
+             * Retrieves whether there are boolean undefined constants in the program.
+             *
+             * @return True iff there are boolean undefined constants in the program.
+             */
             bool hasUndefinedBooleanConstants() const;
+
+            /*!
+             * Retrieves whether there are integer undefined constants in the program.
+             *
+             * @return True iff there are integer undefined constants in the program.
+             */
             bool hasUndefinedIntegerConstants() const;
+            
+            /*!
+             * Retrieves whether there are double undefined constants in the program.
+             *
+             * @return True iff there are double undefined constants in the program.
+             */
             bool hasUndefinedDoubleConstants() const;
             
+            /*!
+             * Retrieves the undefined boolean constants of the program.
+             *
+             * @return The undefined boolean constants of the program.
+             */
             std::set<std::string> const& getUndefinedBooleanConstants() const;
+            
+            /*!
+             * Retrieves the undefined integer constants of the program.
+             *
+             * @return The undefined integer constants of the program.
+             */
             std::set<std::string> const& getUndefinedIntegerConstants() const;
+
+            /*!
+             * Retrieves the undefined double constants of the program.
+             *
+             * @return The undefined double constants of the program.
+             */
             std::set<std::string> const& getUndefinedDoubleConstants() const;
             
-            std::map<std::string, storm::ir::BooleanVariable> const& getGlobalBooleanVariables() const;
+            /*!
+             * Retrieves the global boolean variables of the program.
+             *
+             * @return The global boolean variables of the program.
+             */
+            std::map<std::string, storm::prism::BooleanVariable> const& getGlobalBooleanVariables() const;
             
             /*!
-             * Retrieves a reference to the global boolean variable with the given index.
+             * Retrieves a the global boolean variable with the given name.
              *
-             * @return A reference to the global boolean variable with the given index.
+             * @param variableName The name of the global boolean variable to retrieve.
+             * @return The global boolean variable with the given name.
              */
             storm::ir::BooleanVariable const& getGlobalBooleanVariable(std::string const& variableName) const;
             
-            std::map<std::string, storm::ir::IntegerVariable> const& getGlobalIntegerVariables() const;
+            /*!
+             * Retrieves the global integer variables of the program.
+             *
+             * @return The global integer variables of the program.
+             */
+            std::map<std::string, storm::prism::IntegerVariable> const& getGlobalIntegerVariables() const;
 
             /*!
-             * Retrieves a reference to the global integer variable with the given index.
+             * Retrieves a the global integer variable with the given name.
              *
-             * @return A reference to the global integer variable with the given index.
+             * @param variableName The name of the global integer variable to retrieve.
+             * @return The global integer variable with the given name.
              */
             storm::ir::IntegerVariable const& getGlobalIntegerVariable(std::string const& variableName) const;
 
@@ -109,29 +138,29 @@ namespace storm {
              *
              * @return The number of global boolean variables of the program.
              */
-            uint_fast64_t getNumberOfGlobalBooleanVariables() const;
+            std::size_t getNumberOfGlobalBooleanVariables() const;
             
             /*!
              * Retrieves the number of global integer variables of the program.
              *
              * @return The number of global integer variables of the program.
              */
-            uint_fast64_t getNumberOfGlobalIntegerVariables() const;
+            std::size_t getNumberOfGlobalIntegerVariables() const;
 
             /*!
              * Retrieves the number of modules in the program.
              *
              * @return The number of modules in the program.
              */
-            uint_fast64_t getNumberOfModules() const;
+            std::size_t getNumberOfModules() const;
             
             /*!
-             * Retrieves a reference to the module with the given index.
+             * Retrieves the module with the given index.
              *
              * @param index The index of the module to retrieve.
              * @return The module with the given index.
              */
-            storm::ir::Module const& getModule(uint_fast64_t index) const;
+            storm::prism::Module const& getModule(uint_fast64_t index) const;
             
             /*!
              * Retrieves the set of actions present in the program.
@@ -141,8 +170,8 @@ namespace storm {
             std::set<std::string> const& getActions() const;
             
             /*!
-             * Retrieves the indices of all modules within this program that contain commands that are labelled with the given
-             * action.
+             * Retrieves the indices of all modules within this program that contain commands that are labelled with the
+             * given action.
              *
              * @param action The name of the action the modules are supposed to possess.
              * @return A set of indices of all matching modules.
@@ -157,15 +186,20 @@ namespace storm {
              */
             uint_fast64_t getModuleIndexByVariable(std::string const& variableName) const;
             
-            std::map<std::string, storm::ir::RewardModel> const& getRewardModels() const;
+            /*!
+             * Retrieves the reward models of the program.
+             *
+             * @return The reward models of the program.
+             */
+            std::map<std::string, storm::prism::RewardModel> const& getRewardModels() const;
             
             /*!
              * Retrieves the reward model with the given name.
              *
-             * @param name The name of the reward model to return.
+             * @param rewardModelName The name of the reward model to return.
              * @return The reward model with the given name.
              */
-            storm::ir::RewardModel const& getRewardModel(std::string const& name) const;
+            storm::prism::RewardModel const& getRewardModel(std::string const& rewardModelName) const;
             
             /*!
              * Retrieves all labels that are defined by the probabilitic program.
@@ -200,16 +234,23 @@ namespace storm {
             std::map<std::string, BooleanVariable> globalBooleanVariables;
             
             // A list of global integer variables.
-            std::std::string, IntegerVariable> globalIntegerVariables;
+            std::map<std::string, IntegerVariable> globalIntegerVariables;
             
             // The modules associated with the program.
-            std::vector<storm::ir::Module> modules;
+            std::vector<storm::prism::Module> modules;
             
             // The reward models associated with the program.
-            std::map<std::string, storm::ir::RewardModel> rewardModels;
+            std::map<std::string, storm::prism::RewardModel> rewardModels;
+            
+            // A flag that indicates whether the initial states of the program were given explicitly (in the form of an
+            // initial construct) or implicitly (attached to the variable declarations).
+            bool hasInitialStatesExpression;
+            
+            // The expression contained in the initial construct (if any).
+            storm::expressions::Expression initialStatesExpression;
             
             // The labels that are defined for this model.
-            std::map<std::string, Expression> labels;
+            std::map<std::string, storm::expressions::Expression> labels;
             
             // The set of actions present in this program.
             std::set<std::string> actions;
@@ -221,7 +262,7 @@ namespace storm {
             std::map<std::string, uint_fast64_t> variableToModuleIndexMap;
         };
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_PROGRAM_H_ */
+#endif /* STORM_STORAGE_PRISM_PROGRAM_H_ */
diff --git a/src/storage/prism/RewardModel.cpp b/src/storage/prism/RewardModel.cpp
index 9d6a79ed3..006ee1054 100644
--- a/src/storage/prism/RewardModel.cpp
+++ b/src/storage/prism/RewardModel.cpp
@@ -1,43 +1,20 @@
-/*
- * RewardModel.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "RewardModel.h"
+#include "src/storage/prism/RewardModel.h"
 
 namespace storm {
-    namespace ir {
-        
-        RewardModel::RewardModel() : rewardModelName(), stateRewards(), transitionRewards() {
-            // Nothing to do here.
-        }
-        
-        RewardModel::RewardModel(std::string const& rewardModelName, std::vector<storm::ir::StateReward> const& stateRewards, std::vector<storm::ir::TransitionReward> const& transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) {
+    namespace prism {
+        RewardModel::RewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) {
             // Nothing to do here.
         }
         
-        std::string RewardModel::toString() const {
-            std::stringstream result;
-            result << "rewards \"" << rewardModelName << "\"" << std::endl;
-            for (auto const& reward : stateRewards) {
-                result << reward.toString() << std::endl;
-            }
-            for (auto const& reward : transitionRewards) {
-                result << reward.toString() << std::endl;
-            }
-            result << "endrewards" << std::endl;
-            return result.str();
+        std::string const& RewardModel::getName() const {
+            return this->rewardModelName;
         }
         
         bool RewardModel::hasStateRewards() const {
             return this->stateRewards.size() > 0;
         }
         
-        std::vector<storm::ir::StateReward> const& RewardModel::getStateRewards() const {
+        std::vector<storm::prism::StateReward> const& RewardModel::getStateRewards() const {
             return this->stateRewards;
         }
         
@@ -45,9 +22,21 @@ namespace storm {
             return this->transitionRewards.size() > 0;
         }
         
-        std::vector<storm::ir::TransitionReward> const& RewardModel::getTransitionRewards() const {
+        std::vector<storm::prism::TransitionReward> const& RewardModel::getTransitionRewards() const {
             return this->transitionRewards;
         }
         
-    } // namespace ir
+        std::ostream& operator<<(std::ostream& stream, RewardModel const& rewardModel) {
+            stream << "rewards \"" << rewardModel.getName() << "\"" << std::endl;
+            for (auto const& reward : rewardModel.getStateRewards()) {
+                stream << reward << std::endl;
+            }
+            for (auto const& reward : rewardModel.getTransitionRewards()) {
+                stream << reward << std::endl;
+            }
+            stream << "endrewards" << std::endl;
+            return stream;
+        }
+        
+    } // namespace prism
 } // namespace storm
diff --git a/src/storage/prism/RewardModel.h b/src/storage/prism/RewardModel.h
index 827248810..6c172c744 100644
--- a/src/storage/prism/RewardModel.h
+++ b/src/storage/prism/RewardModel.h
@@ -1,88 +1,81 @@
-/*
- * RewardModel.h
- *
- *  Created on: 04.01.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_REWARDMODEL_H_
-#define STORM_IR_REWARDMODEL_H_
+#ifndef STORM_STORAGE_PRISM_REWARDMODEL_H_
+#define STORM_STORAGE_PRISM_REWARDMODEL_H_
 
 #include <string>
 #include <vector>
 
-#include "StateReward.h"
-#include "TransitionReward.h"
+#include "src/storage/prism/StateReward.h"
+#include "src/storage/prism/TransitionReward.h"
 
 namespace storm {
-    namespace ir {
-        
-        /*!
-         * A class representing a reward model.
-         */
+    namespace prism {
         class RewardModel {
         public:
             /*!
-             * Default constructor. Creates an empty reward model.
-             */
-            RewardModel();
-            
-            /*!
-             * Creates a reward module with the given name, state and transition rewards.
+             * Creates a reward model with the given name, state and transition rewards.
              *
              * @param rewardModelName The name of the reward model.
              * @param stateRewards A vector of state-based rewards.
              * @param transitionRewards A vector of transition-based rewards.
              */
-            RewardModel(std::string const& rewardModelName, std::vector<storm::ir::StateReward> const& stateRewards, std::vector<storm::ir::TransitionReward> const& transitionRewards);
+            RewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards);
+            
+            // Create default implementations of constructors/assignment.
+            RewardModel() = default;
+            RewardModel(RewardModel const& otherVariable) = default;
+            RewardModel& operator=(RewardModel const& otherVariable)= default;
+            RewardModel(RewardModel&& otherVariable) = default;
+            RewardModel& operator=(RewardModel&& otherVariable) = default;
             
             /*!
-             * Retrieves a string representation of this reward model.
+             * Retrieves the name of the reward model.
              *
-             * @return a string representation of this reward model.
+             * @return The name of the reward model.
              */
-            std::string toString() const;
+            std::string const& getName() const;
             
             /*!
-             * Check, if there are any state rewards.
+             * Retrieves whether there are any state rewards.
              *
-             * @return True, iff there are any state rewards.
+             * @return True iff there are any state rewards.
              */
             bool hasStateRewards() const;
             
             /*!
-             * Retrieves a vector of state rewards associated with this reward model.
+             * Retrieves all state rewards associated with this reward model.
              *
-             * @return A vector containing the state rewards associated with this reward model.
+             * @return The state rewards associated with this reward model.
              */
-            std::vector<storm::ir::StateReward> const& getStateRewards() const;
+            std::vector<storm::prism::StateReward> const& getStateRewards() const;
             
             /*!
-             * Check, if there are any transition rewards.
+             * Retrieves whether there are any transition rewards.
              *
-             * @return True, iff there are any transition rewards associated with this reward model.
+             * @return True iff there are any transition rewards.
              */
             bool hasTransitionRewards() const;
             
             /*!
-             * Retrieves a vector of transition rewards associated with this reward model.
+             * Retrieves all transition rewards associated with this reward model.
              *
-             * @return A vector of transition rewards associated with this reward model.
+             * @return The transition rewards associated with this reward model.
              */
-            std::vector<storm::ir::TransitionReward> const& getTransitionRewards() const;
+            std::vector<storm::prism::TransitionReward> const& getTransitionRewards() const;
             
+            friend std::ostream& operator<<(std::ostream& stream, RewardModel const& rewardModel);
+
         private:
             // The name of the reward model.
             std::string rewardModelName;
             
             // The state-based rewards associated with this reward model.
-            std::vector<storm::ir::StateReward> stateRewards;
+            std::vector<storm::prism::StateReward> stateRewards;
             
             // The transition-based rewards associated with this reward model.
-            std::vector<storm::ir::TransitionReward> transitionRewards;
+            std::vector<storm::prism::TransitionReward> transitionRewards;
         };
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_REWARDMODEL_H_ */
+#endif /* STORM_STORAGE_PRISM_REWARDMODEL_H_ */
diff --git a/src/storage/prism/StateReward.cpp b/src/storage/prism/StateReward.cpp
index 50457cabc..c4bcbd428 100644
--- a/src/storage/prism/StateReward.cpp
+++ b/src/storage/prism/StateReward.cpp
@@ -1,38 +1,22 @@
-/*
- * StateReward.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "StateReward.h"
+#include "src/storage/prism/StateReward.h"
 
 namespace storm {
-    namespace ir {
-        
-        StateReward::StateReward() : statePredicate(), rewardValue() {
+    namespace prism {
+        StateReward::StateReward(storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression) : statePredicateExpression(statePredicateExpression), rewardValueExpression(rewardValueExpression) {
             // Nothing to do here.
         }
         
-        StateReward::StateReward(storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue) : statePredicate(statePredicate), rewardValue(rewardValue) {
-            // Nothing to do here.
+        storm::expressions::Expression const& StateReward::getStatePredicateExpression() const {
+            return this->statePredicateExpression;
         }
         
-        std::string StateReward::toString() const {
-            std::stringstream result;
-            result << "\t" << statePredicate << ": " << rewardValue << ";";
-            return result.str();
+        storm::expressions::Expression const& StateReward::getRewardValueExpression() const {
+            return this->rewardValueExpression;
         }
         
-        storm::expressions::Expression const& StateReward::getStatePredicate() const {
-            return this->statePredicate;
+        std::ostream& operator<<(std::ostream& stream, StateReward const& stateReward) {
+            stream << "\t" << stateReward.getStatePredicateExpression() << ": " << stateReward.getRewardValueExpression() << ";";
+            return stream;
         }
-        
-        storm::expressions::Expression const& StateReward::getRewardValue() const {
-            return this->rewardValue;
-        }
-        
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
diff --git a/src/storage/prism/StateReward.h b/src/storage/prism/StateReward.h
index d8c09f4e2..bdd08d446 100644
--- a/src/storage/prism/StateReward.h
+++ b/src/storage/prism/StateReward.h
@@ -1,85 +1,53 @@
-/*
- * StateReward.h
- *
- *  Created on: Jan 10, 2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_STATEREWARD_H_
-#define STORM_IR_STATEREWARD_H_
-
-#include <memory>
+#ifndef STORM_STORAGE_PRISM_STATEREWARD_H_
+#define STORM_STORAGE_PRISM_STATEREWARD_H_
 
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
-    namespace ir {
-        
-        /*!
-         * A class representing a state reward.
-         */
+    namespace prism {
         class StateReward {
         public:
             /*!
-             * Default constructor. Creates an empty state reward.
-             */
-            StateReward();
-            
-            /*!
-             * Creates a state reward for the states satisfying the given expression with the value given
-             * by a second expression.
-             *
-             * @param statePredicate The predicate that states earning this state-based reward need to
-             * satisfy.
-             * @param rewardValue An expression specifying the values of the rewards to attach to the
-             * states.
-             */
-            StateReward(storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue);
-            
-            /*!
-             * Performs a deep-copy of the given reward.
-             *
-             * @param otherReward The reward to copy.
-             */
-            StateReward(StateReward const& otherReward) = default;
-
-            /*!
-             * Performs a deep-copy of the given reward and assigns it to the current one.
+             * Creates a state reward for the states satisfying the given expression with the value given by a second
+             * expression.
              *
-             * @param otherReward The reward to assign.
+             * @param statePredicateExpression The predicate that states earning this state-based reward need to satisfy.
+             * @param rewardValueExpression An expression specifying the values of the rewards to attach to the states.
              */
-            StateReward& operator=(StateReward const& otherReward) = default;
+            StateReward(storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression);
             
-            /*!
-             * Retrieves a string representation of this state reward.
-             *
-             * @return A string representation of this state reward.
-             */
-            std::string toString() const;
+            // Create default implementations of constructors/assignment.
+            StateReward() = default;
+            StateReward(StateReward const& otherVariable) = default;
+            StateReward& operator=(StateReward const& otherVariable)= default;
+            StateReward(StateReward&& otherVariable) = default;
+            StateReward& operator=(StateReward&& otherVariable) = default;
             
             /*!
              * Retrieves the state predicate that is associated with this state reward.
              *
              * @return The state predicate that is associated with this state reward.
              */
-            storm::expressions::Expression const& getStatePredicate() const;
+            storm::expressions::Expression const& getStatePredicateExpression() const;
             
             /*!
              * Retrieves the reward value associated with this state reward.
              *
              * @return The reward value associated with this state reward.
              */
-            storm::expressions::Expression const& getRewardValue() const;
+            storm::expressions::Expression const& getRewardValueExpression() const;
             
+            friend std::ostream& operator<<(std::ostream& stream, StateReward const& stateReward);
+
         private:
             // The predicate that characterizes the states that obtain this reward.
-            storm::expressions::Expression statePredicate;
+            storm::expressions::Expression statePredicateExpression;
             
             // The expression that specifies the value of the reward obtained.
-            storm::expressions::Expression rewardValue;
+            storm::expressions::Expression rewardValueExpression;
         };
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_STATEREWARD_H_ */
+#endif /* STORM_STORAGE_PRISM_STATEREWARD_H_ */
diff --git a/src/storage/prism/TransitionReward.cpp b/src/storage/prism/TransitionReward.cpp
index 93d951731..f972f1270 100644
--- a/src/storage/prism/TransitionReward.cpp
+++ b/src/storage/prism/TransitionReward.cpp
@@ -1,42 +1,27 @@
-/*
- * TransitionReward.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-
-#include "TransitionReward.h"
+#include "src/storage/prism/TransitionReward.h"
 
 namespace storm {
-    namespace ir {
-        
-        TransitionReward::TransitionReward() : commandName(), statePredicate(), rewardValue() {
-            // Nothing to do here.
-        }
-        
-        TransitionReward::TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue) : commandName(commandName), statePredicate(statePredicate), rewardValue(rewardValue) {
+    namespace prism {
+        TransitionReward::TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression) : commandName(commandName), statePredicateExpression(statePredicateExpression), rewardValueExpression(rewardValueExpression) {
             // Nothing to do here.
         }
         
-        std::string TransitionReward::toString() const {
-            std::stringstream result;
-            result << "\t[" << commandName << "] " << statePredicate << ": " << rewardValue << ";";
-            return result.str();
-        }
-        
         std::string const& TransitionReward::getActionName() const {
             return this->commandName;
         }
         
-        storm::expressions::Expression const& TransitionReward::getStatePredicate() const {
-            return this->statePredicate;
+        storm::expressions::Expression const& TransitionReward::getStatePredicateExpression() const {
+            return this->statePredicateExpression;
+        }
+        
+        storm::expressions::Expression const& TransitionReward::getRewardValueExpression() const {
+            return this->rewardValueExpression;
         }
         
-        storm::expressions::Expression const& TransitionReward::getRewardValue() const {
-            return this->rewardValue;
+        std::ostream& operator<<(std::ostream& stream, TransitionReward const& transitionReward) {
+            stream << "\t[" << transitionReward.getActionName() << "] " << transitionReward.getStatePredicateExpression() << ": " << transitionReward.getRewardValueExpression() << ";";
+            return stream;
         }
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
diff --git a/src/storage/prism/TransitionReward.h b/src/storage/prism/TransitionReward.h
index b21eeb12f..1fb783101 100644
--- a/src/storage/prism/TransitionReward.h
+++ b/src/storage/prism/TransitionReward.h
@@ -1,99 +1,66 @@
-/*
- * TransitionReward.h
- *
- *  Created on: Jan 10, 2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_IR_TRANSITIONREWARD_H_
-#define STORM_IR_TRANSITIONREWARD_H_
-
-#include <memory>
+#ifndef STORM_STORAGE_PRISM_TRANSITIONREWARD_H_
+#define STORM_STORAGE_PRISM_TRANSITIONREWARD_H_
 
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
+    namespace prism {
+        class TransitionReward {
+        public:
+            /*!
+             * Creates a transition reward for the transitions with the given name emanating from states satisfying the
+             * given expression with the value given by another expression.
+             *
+             * @param actionName The name of the command that obtains this reward.
+             * @param statePredicateExpression The predicate that needs to hold before taking a transition with the previously
+             * specified name in order to obtain the reward.
+             * @param rewardValueExpression An expression specifying the values of the rewards to attach to the transitions.
+             */
+            TransitionReward(std::string const& actionName, storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression);
+            
+            // Create default implementations of constructors/assignment.
+            TransitionReward() = default;
+            TransitionReward(TransitionReward const& otherVariable) = default;
+            TransitionReward& operator=(TransitionReward const& otherVariable)= default;
+            TransitionReward(TransitionReward&& otherVariable) = default;
+            TransitionReward& operator=(TransitionReward&& otherVariable) = default;
+            
+            /*!
+             * Retrieves the action name that is associated with this transition reward.
+             *
+             * @return The action name that is associated with this transition reward.
+             */
+            std::string const& getActionName() const;
+            
+            /*!
+             * Retrieves the state predicate expression that is associated with this state reward.
+             *
+             * @return The state predicate expression that is associated with this state reward.
+             */
+            storm::expressions::Expression const& getStatePredicateExpression() const;
+            
+            /*!
+             * Retrieves the reward value expression associated with this state reward.
+             *
+             * @return The reward value expression associated with this state reward.
+             */
+            storm::expressions::Expression const& getRewardValueExpression() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, TransitionReward const& transitionReward);
 
-namespace ir {
-
-/*!
- * A class representing a transition reward.
- */
-class TransitionReward {
-public:
-	/*!
-	 * Default constructor. Creates an empty transition reward.
-	 */
-	TransitionReward();
-
-	/*!
-	 * Creates a transition reward for the transitions with the given name emanating from states
-	 * satisfying the given expression with the value given by another expression.
-     *
-	 * @param commandName The name of the command that obtains this reward.
-	 * @param statePredicate The predicate that needs to hold before taking a transition with the
-	 * previously specified name in order to obtain the reward.
-	 * @param rewardValue An expression specifying the values of the rewards to attach to the
-	 * transitions.
-	 */
-	TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicate, storm::expressions::Expression const& rewardValue);
-
-    /*!
-     * Performs a deep-copy of the given transition reward.
-     *
-     * @param otherReward The transition reward to copy.
-     */
-    TransitionReward(TransitionReward const& otherReward) = default;
-    
-    /*!
-     * Performs a deep-copy of the given transition reward and assigns it to the current one.
-     *
-     * @param otherReward The reward to assign.
-     */
-    TransitionReward& operator=(TransitionReward const& otherReward) = default;
-    
-	/*!
-	 * Retrieves a string representation of this transition reward.
-     *
-	 * @return A string representation of this transition reward.
-	 */
-	std::string toString() const;
-    
-    /*!
-     * Retrieves the action name that is associated with this transition reward.
-     *
-     * @return The action name that is associated with this transition reward.
-     */
-    std::string const& getActionName() const;
-    
-    /*!
-     * Retrieves the state predicate that is associated with this state reward.
-     *
-     * @return The state predicate that is associated with this state reward.
-     */
-    storm::expressions::Expression const& getStatePredicate() const;
-    
-    /*!
-     * Retrieves the reward value associated with this state reward.
-     *
-     * @return The reward value associated with this state reward.
-     */
-    storm::expressions::Expression const& getRewardValue() const;
-
-private:
-	// The name of the command this transition-based reward is attached to.
-	std::string commandName;
-
-	// A predicate that needs to be satisfied by states for the reward to be obtained (by taking
-	// a corresponding command transition).
-	storm::expressions::Expression statePredicate;
-
-	// The expression specifying the value of the reward obtained along the transitions.
-	storm::expressions::Expression rewardValue;
-};
-
-} // namespace ir
-
+        private:
+            // The name of the command this transition-based reward is attached to.
+            std::string commandName;
+            
+            // A predicate that needs to be satisfied by states for the reward to be obtained (by taking
+            // a corresponding command transition).
+            storm::expressions::Expression statePredicateExpression;
+            
+            // The expression specifying the value of the reward obtained along the transitions.
+            storm::expressions::Expression rewardValueExpression;
+        };
+        
+    } // namespace prism
 } // namespace storm
 
-#endif /* STORM_IR_TRANSITIONREWARD_H_ */
+#endif /* STORM_STORAGE_PRISM_TRANSITIONREWARD_H_ */

From d87c79d0f6d35162f91f7a24a5d168acbd054c9a Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 7 Apr 2014 22:54:47 +0200
Subject: [PATCH 062/147] Added implies/iff to expression classes. Finished
 reworking PRISM classes.

Former-commit-id: ca202042ed267b476c6cc900267b5cb031d79614
---
 .../BinaryBooleanFunctionExpression.cpp       |  21 +-
 .../BinaryBooleanFunctionExpression.h         |   2 +-
 src/storage/expressions/Expression.cpp        |  10 +
 src/storage/expressions/Expression.h          |   3 +
 src/storage/prism/Module.cpp                  |   2 +-
 src/storage/prism/Module.h                    |   4 +-
 src/storage/prism/Program.cpp                 | 365 +++++++-----------
 src/storage/prism/Program.h                   |  35 +-
 src/storage/prism/Update.cpp                  |   2 +-
 9 files changed, 206 insertions(+), 238 deletions(-)

diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index 8f5abf57c..90ba44885 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -1,5 +1,5 @@
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
-
+#include "src/storage/expressions/BooleanLiteralExpression.h"
 #include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/InvalidTypeException.h"
 
@@ -23,6 +23,8 @@ namespace storm {
             switch (this->getOperatorType()) {
                 case OperatorType::And: result = firstOperandEvaluation && secondOperandEvaluation; break;
                 case OperatorType::Or: result = firstOperandEvaluation || secondOperandEvaluation; break;
+                case OperatorType::Implies: result = !firstOperandEvaluation || secondOperandEvaluation; break;
+                case OperatorType::Iff: result = (firstOperandEvaluation && secondOperandEvaluation) || (!firstOperandEvaluation && !secondOperandEvaluation); break;
             }
             
             return result;
@@ -52,6 +54,21 @@ namespace storm {
                 } else if (secondOperandSimplified->isFalse()) {
                     return firstOperandSimplified;
                 }
+                break;
+                case OperatorType::Implies: if (firstOperandSimplified->isTrue()) {
+                    return secondOperandSimplified;
+                } else if (firstOperandSimplified->isFalse()) {
+                    return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(true));
+                } else if (secondOperandSimplified->isTrue()) {
+                    return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(true));
+                }
+                break;
+                case OperatorType::Iff: if (firstOperandSimplified->isTrue() && secondOperandSimplified->isTrue()) {
+                    return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(true));
+                } else if (firstOperandSimplified->isFalse() && secondOperandSimplified->isFalse()) {
+                    return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(true));
+                }
+                break;
             }
             
             // If the two successors remain unchanged, we can return a shared_ptr to this very object.
@@ -71,6 +88,8 @@ namespace storm {
             switch (this->getOperatorType()) {
                 case OperatorType::And: stream << " && "; break;
                 case OperatorType::Or: stream << " || "; break;
+                case OperatorType::Implies: stream << " => "; break;
+                case OperatorType::Iff: stream << " <=> "; break;
             }
             stream << *this->getSecondOperand() << ")";
         }
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index 41ae92b7b..b4f8ad0a6 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -10,7 +10,7 @@ namespace storm {
             /*!
              * An enum type specifying the different operators applicable.
              */
-            enum class OperatorType {And, Or};
+            enum class OperatorType {And, Or, Implies, Iff};
             
             /*!
              * Creates a binary boolean function expression with the given return type, operands and operator.
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 0c641d3ec..b94d98db8 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -216,6 +216,16 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(lhs.getReturnType() == ExpressionReturnType::Int && rhs.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, lhs.getBaseExpressionPointer(), rhs.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Max)));
         }
         
+        Expression Expression::implies(Expression const& other) const {
+            LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '&&' requires boolean operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Implies)));
+        }
+        
+        Expression Expression::iff(Expression const& other) const {
+            LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '&&' requires boolean operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Iff)));
+        }
+        
         Expression Expression::floor() const {
             LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator 'floor' requires numerical operand.");
             return Expression(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(ExpressionReturnType::Int, this->getBaseExpressionPointer(), UnaryNumericalFunctionExpression::OperatorType::Floor)));
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 3002e4d35..875bcfbdc 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -53,6 +53,9 @@ namespace storm {
             Expression operator<(Expression const& other) const;
             Expression operator<=(Expression const& other) const;
             
+            Expression implies(Expression const& other) const;
+            Expression iff(Expression const& other) const;
+            
             Expression floor() const;
             Expression ceil() const;
 
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 6da269889..5a90c4bda 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -122,7 +122,7 @@ namespace storm {
             }
         }
         
-        Module Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
+        Module Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) const {
             // First construct the new vector of commands.
             std::vector<storm::prism::Command> newCommands;
             for (auto const& command : commands) {
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index 595a48c5c..789cd0e09 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -147,7 +147,7 @@ namespace storm {
              * @param indexSet The set of indices for which to keep the commands.
              * @return The module resulting from erasing all commands whose indices are not in the given set.
              */
-            Module restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
+            Module restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) const;
             
             friend std::ostream& operator<<(std::ostream& stream, Module const& module);
 
@@ -167,7 +167,7 @@ namespace storm {
             std::map<std::string, storm::prism::IntegerVariable> integerVariables;
             
             // The commands associated with the module.
-            std::vector<storm::ir::Command> commands;
+            std::vector<storm::prism::Command> commands;
             
             // The set of actions present in this module.
             std::set<std::string> actions;
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 33c75c44f..a688a63dd 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -1,63 +1,18 @@
-/*
- * Program.cpp
- *
- *  Created on: 12.01.2013
- *      Author: Christian Dehnert
- */
-
-#include <sstream>
-#include <iostream>
-
-#include "Program.h"
+#include "src/storage/prism/Program.h"
+#include "src/exceptions/ExceptionMacros.h"
 #include "exceptions/InvalidArgumentException.h"
 #include "src/exceptions/OutOfRangeException.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
 namespace storm {
-    namespace ir {
-        
-        Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
-            // Nothing to do here.
-        }
-        
-        Program::Program(ModelType modelType,
-                         std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& booleanUndefinedConstantExpressions,
-                         std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& integerUndefinedConstantExpressions,
-                         std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& doubleUndefinedConstantExpressions,
-                         std::vector<BooleanVariable> const& globalBooleanVariables,
-                         std::vector<IntegerVariable> const& globalIntegerVariables,
-                         std::map<std::string, uint_fast64_t> const& globalBooleanVariableToIndexMap,
-                         std::map<std::string, uint_fast64_t> const& globalIntegerVariableToIndexMap,
-                         std::vector<storm::ir::Module> const& modules,
-                         std::map<std::string, storm::ir::RewardModel> const& rewards,
-                         std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels)
-        : modelType(modelType), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables),
-        globalBooleanVariableToIndexMap(globalBooleanVariableToIndexMap), globalIntegerVariableToIndexMap(globalIntegerVariableToIndexMap),
-        modules(modules), rewards(rewards), actionsToModuleIndexMap(), variableToModuleIndexMap() {
-            
-            // Perform a deep-copy of the maps.
-            for (auto const& booleanUndefinedConstant : booleanUndefinedConstantExpressions) {
-                this->booleanUndefinedConstantExpressions[booleanUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>(new storm::ir::expressions::BooleanConstantExpression(*booleanUndefinedConstant.second));
-            }
-            for (auto const& integerUndefinedConstant : integerUndefinedConstantExpressions) {
-                this->integerUndefinedConstantExpressions[integerUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>(new storm::ir::expressions::IntegerConstantExpression(*integerUndefinedConstant.second));
-            }
-            for (auto const& doubleUndefinedConstant : doubleUndefinedConstantExpressions) {
-                this->doubleUndefinedConstantExpressions[doubleUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>(new storm::ir::expressions::DoubleConstantExpression(*doubleUndefinedConstant.second));
-            }
-            for (auto const& label : labels) {
-                this->labels[label.first] = label.second->clone();
-            }
-            
+    namespace prism {
+        Program::Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels) : modelType(modelType), undefinedBooleanConstants(undefinedBooleanConstants), undefinedIntegerConstants(undefinedIntegerConstants), undefinedDoubleConstants(undefinedDoubleConstants), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables), modules(modules), rewardModels(rewardModels), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
             // Now build the mapping from action names to module indices so that the lookup can later be performed quickly.
-            for (unsigned int moduleIndex = 0; moduleIndex < this->modules.size(); moduleIndex++) {
-                Module const& module = this->modules[moduleIndex];
+            for (unsigned int moduleIndex = 0; moduleIndex < this->getNumberOfModules(); moduleIndex++) {
+                Module const& module = this->getModule(moduleIndex);
                 
                 for (auto const& action : module.getActions()) {
-                    if (this->actionsToModuleIndexMap.count(action) == 0) {
+                    auto const& actionModuleIndicesPair = this->actionsToModuleIndexMap.find(action);
+                    if (actionModuleIndicesPair == this->actionsToModuleIndexMap.end()) {
                         this->actionsToModuleIndexMap[action] = std::set<uint_fast64_t>();
                     }
                     this->actionsToModuleIndexMap[action].insert(moduleIndex);
@@ -65,235 +20,195 @@ namespace storm {
                 }
                 
                 // Put in the appropriate entries for the mapping from variable names to module index.
-                for (uint_fast64_t booleanVariableIndex = 0; booleanVariableIndex < module.getNumberOfBooleanVariables(); ++booleanVariableIndex) {
-                    this->variableToModuleIndexMap[module.getBooleanVariable(booleanVariableIndex).getName()] = moduleIndex;
-                }
-                for (uint_fast64_t integerVariableIndex = 0; integerVariableIndex < module.getNumberOfIntegerVariables(); ++integerVariableIndex) {
-                    this->variableToModuleIndexMap[module.getIntegerVariable(integerVariableIndex).getName()] = moduleIndex;
-                }
-            }
-        }
-        
-        Program::Program(Program const& otherProgram) : modelType(otherProgram.modelType), globalBooleanVariables(otherProgram.globalBooleanVariables),
-        globalIntegerVariables(otherProgram.globalIntegerVariables), globalBooleanVariableToIndexMap(otherProgram.globalBooleanVariableToIndexMap),
-        globalIntegerVariableToIndexMap(otherProgram.globalIntegerVariableToIndexMap), modules(otherProgram.modules), rewards(otherProgram.rewards),
-        actions(otherProgram.actions), actionsToModuleIndexMap(), variableToModuleIndexMap() {
-            // Perform deep-copy of the maps.
-            for (auto const& booleanUndefinedConstant : otherProgram.booleanUndefinedConstantExpressions) {
-                this->booleanUndefinedConstantExpressions[booleanUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>(new storm::ir::expressions::BooleanConstantExpression(*booleanUndefinedConstant.second));
-            }
-            for (auto const& integerUndefinedConstant : otherProgram.integerUndefinedConstantExpressions) {
-                this->integerUndefinedConstantExpressions[integerUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>(new storm::ir::expressions::IntegerConstantExpression(*integerUndefinedConstant.second));
-            }
-            for (auto const& doubleUndefinedConstant : otherProgram.doubleUndefinedConstantExpressions) {
-                this->doubleUndefinedConstantExpressions[doubleUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>(new storm::ir::expressions::DoubleConstantExpression(*doubleUndefinedConstant.second));
-            }
-            for (auto const& label : otherProgram.labels) {
-                this->labels[label.first] = label.second->clone();
-            }
-        }
-        
-        Program& Program::operator=(Program const& otherProgram) {
-            if (this != &otherProgram) {
-                this->modelType = otherProgram.modelType;
-                this->globalBooleanVariables = otherProgram.globalBooleanVariables;
-                this->globalIntegerVariables = otherProgram.globalIntegerVariables;
-                this->globalBooleanVariableToIndexMap = otherProgram.globalBooleanVariableToIndexMap;
-                this->globalIntegerVariableToIndexMap = otherProgram.globalIntegerVariableToIndexMap;
-                this->modules = otherProgram.modules;
-                this->rewards = otherProgram.rewards;
-                this->actions = otherProgram.actions;
-                this->actionsToModuleIndexMap = otherProgram.actionsToModuleIndexMap;
-                this->variableToModuleIndexMap = otherProgram.variableToModuleIndexMap;
-                
-                // Perform deep-copy of the maps.
-                for (auto const& booleanUndefinedConstant : otherProgram.booleanUndefinedConstantExpressions) {
-                    this->booleanUndefinedConstantExpressions[booleanUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>(new storm::ir::expressions::BooleanConstantExpression(*booleanUndefinedConstant.second));
-                }
-                for (auto const& integerUndefinedConstant : otherProgram.integerUndefinedConstantExpressions) {
-                    this->integerUndefinedConstantExpressions[integerUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>(new storm::ir::expressions::IntegerConstantExpression(*integerUndefinedConstant.second));
+                for (auto const& booleanVariable : module.getBooleanVariables()) {
+                    this->variableToModuleIndexMap[booleanVariable.first] = moduleIndex;
                 }
-                for (auto const& doubleUndefinedConstant : otherProgram.doubleUndefinedConstantExpressions) {
-                    this->doubleUndefinedConstantExpressions[doubleUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>(new storm::ir::expressions::DoubleConstantExpression(*doubleUndefinedConstant.second));
-                }
-                for (auto const& label : otherProgram.labels) {
-                    this->labels[label.first] = label.second->clone();
+                for (auto const& integerVariable : module.getBooleanVariables()) {
+                    this->variableToModuleIndexMap[integerVariable.first] = moduleIndex;
                 }
             }
-            
-            return *this;
         }
         
         Program::ModelType Program::getModelType() const {
             return modelType;
         }
         
-        std::string Program::toString() const {
-            std::stringstream result;
-            switch (modelType) {
-                case UNDEFINED: result << "undefined"; break;
-                case DTMC: result << "dtmc"; break;
-                case CTMC: result << "ctmc"; break;
-                case MDP: result << "mdp"; break;
-                case CTMDP: result << "ctmdp"; break;
-            }
-            result << std::endl;
-            
-            for (auto const& element : booleanUndefinedConstantExpressions) {
-                result << "const bool " << element.second->toString() << ";" << std::endl;
-            }
-            for (auto const& element : integerUndefinedConstantExpressions) {
-                result << "const int " << element.second->toString() << ";" << std::endl;
-            }
-            for (auto const& element : doubleUndefinedConstantExpressions) {
-                result << "const double " << element.second->toString() << ";" << std::endl;
-            }
-            result << std::endl;
-            
-            for (auto const& element : globalBooleanVariables) {
-                result << "global " << element.toString() << std::endl;
-            }
-            for (auto const& element : globalIntegerVariables) {
-                result << "global " << element.toString() << std::endl;
-            }
-            result << std::endl;
-            
-            for (auto const& module : modules) {
-                result << module.toString() << std::endl;
-            }
-            
-            for (auto const& rewardModel : rewards) {
-                result << rewardModel.second.toString() << std::endl;
-            }
-            
-            for (auto const& label : labels) {
-                result << "label \"" << label.first << "\" = " << label.second->toString() <<";" << std::endl;
-            }
-            
-            return result.str();
+        bool Program::hasUndefinedConstants() const {
+            return this->hasUndefinedBooleanConstants() || this->hasUndefinedIntegerConstants() || this->hasUndefinedDoubleConstants();
         }
         
-        storm::ir::BooleanVariable const& Program::getGlobalBooleanVariable(uint_fast64_t index) const {
-            return this->globalBooleanVariables[index];
+        bool Program::hasUndefinedBooleanConstants() const {
+            return !this->undefinedBooleanConstants.empty();
         }
         
-        storm::ir::IntegerVariable const& Program::getGlobalIntegerVariable(uint_fast64_t index) const {
-            return this->globalIntegerVariables[index];
+        bool Program::hasUndefinedIntegerConstants() const {
+            return !this->undefinedIntegerConstants.empty();
         }
         
-        uint_fast64_t Program::getNumberOfModules() const {
-            return this->modules.size();
+        bool Program::hasUndefinedDoubleConstants() const {
+            return !this->undefinedDoubleConstants.empty();
         }
         
-        storm::ir::Module const& Program::getModule(uint_fast64_t index) const {
-            return this->modules[index];
+        std::set<std::string> const& Program::getUndefinedBooleanConstants() const {
+            return this->undefinedBooleanConstants;
         }
-        
-        std::set<std::string> const& Program::getActions() const {
-            return this->actions;
+
+        std::set<std::string> const& Program::getUndefinedIntegerConstants() const {
+            return this->undefinedIntegerConstants;
         }
         
-        std::set<uint_fast64_t> const& Program::getModulesByAction(std::string const& action) const {
-            auto actionModuleSetPair = this->actionsToModuleIndexMap.find(action);
-            if (actionModuleSetPair == this->actionsToModuleIndexMap.end()) {
-                LOG4CPLUS_ERROR(logger, "Action name '" << action << "' does not exist.");
-                throw storm::exceptions::OutOfRangeException() << "Action name '" << action << "' does not exist.";
-            }
-            return actionModuleSetPair->second;
+        std::set<std::string> const& Program::getUndefinedDoubleConstants() const {
+            return this->undefinedDoubleConstants;
         }
         
-        uint_fast64_t Program::getModuleIndexForVariable(std::string const& variableName) const {
-            auto variableNameToModuleIndexPair = this->variableToModuleIndexMap.find(variableName);
-            if (variableNameToModuleIndexPair != this->variableToModuleIndexMap.end()) {
-                return variableNameToModuleIndexPair->second;
-            }
-            throw storm::exceptions::OutOfRangeException() << "Variable '" << variableName << "' does not exist.";
+        std::map<std::string, storm::prism::BooleanVariable> const& Program::getGlobalBooleanVariables() const {
+            return this->globalBooleanVariables;
+        }
+
+        storm::prism::BooleanVariable const& Program::getGlobalBooleanVariable(std::string const& variableName) const {
+            auto const& nameVariablePair = this->getGlobalBooleanVariables().find(variableName);
+            LOG_THROW(nameVariablePair != this->getGlobalBooleanVariables().end(), storm::exceptions::OutOfRangeException, "Unknown boolean variable '" << variableName << "'.");
+            return nameVariablePair->second;
         }
         
-        uint_fast64_t Program::getNumberOfGlobalBooleanVariables() const {
-            return this->globalBooleanVariables.size();
+        std::map<std::string, storm::prism::IntegerVariable> const& Program::getGlobalIntegerVariables() const {
+            return this->globalIntegerVariables;
+        }
+
+        storm::prism::IntegerVariable const& Program::getGlobalIntegerVariable(std::string const& variableName) const {
+            auto const& nameVariablePair = this->getGlobalIntegerVariables().find(variableName);
+            LOG_THROW(nameVariablePair != this->getGlobalIntegerVariables().end(), storm::exceptions::OutOfRangeException, "Unknown integer variable '" << variableName << "'.");
+            return nameVariablePair->second;
         }
         
-        uint_fast64_t Program::getNumberOfGlobalIntegerVariables() const {
-            return this->globalIntegerVariables.size();
+        std::size_t Program::getNumberOfGlobalBooleanVariables() const {
+            return this->getGlobalBooleanVariables().size();
         }
         
-        storm::ir::RewardModel const& Program::getRewardModel(std::string const& name) const {
-            auto nameRewardModelPair = this->rewards.find(name);
-            if (nameRewardModelPair == this->rewards.end()) {
-                LOG4CPLUS_ERROR(logger, "Reward model '" << name << "' does not exist.");
-                throw storm::exceptions::OutOfRangeException() << "Reward model '" << name << "' does not exist.";
-            }
-            return nameRewardModelPair->second;
+        std::size_t Program::getNumberOfGlobalIntegerVariables() const {
+            return this->getGlobalIntegerVariables().size();
         }
         
-        std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& Program::getLabels() const {
-            return this->labels;
+        std::size_t Program::getNumberOfModules() const {
+            return this->getModules().size();
         }
         
-        bool Program::hasUndefinedBooleanConstant(std::string const& constantName) const {
-            return this->booleanUndefinedConstantExpressions.find(constantName) != this->booleanUndefinedConstantExpressions.end();
+        storm::prism::Module const& Program::getModule(uint_fast64_t index) const {
+            return this->modules[index];
         }
         
-        std::unique_ptr<storm::ir::expressions::BooleanConstantExpression> const& Program::getUndefinedBooleanConstantExpression(std::string const& constantName) const {
-            auto constantExpressionPair = this->booleanUndefinedConstantExpressions.find(constantName);
-            if (constantExpressionPair != this->booleanUndefinedConstantExpressions.end()) {
-                return constantExpressionPair->second;
-            } else {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown undefined boolean constant " << constantName << ".";
-            }
+        std::vector<storm::prism::Module> const& Program::getModules() const {
+            return this->modules;
         }
         
-        bool Program::hasUndefinedIntegerConstant(std::string const& constantName) const {
-            return this->integerUndefinedConstantExpressions.find(constantName) != this->integerUndefinedConstantExpressions.end();
+        bool Program::definesInitialStatesExpression() const {
+            return this->hasInitialStatesExpression;
         }
         
-        std::unique_ptr<storm::ir::expressions::IntegerConstantExpression> const& Program::getUndefinedIntegerConstantExpression(std::string const& constantName) const {
-            auto constantExpressionPair = this->integerUndefinedConstantExpressions.find(constantName);
-            if (constantExpressionPair != this->integerUndefinedConstantExpressions.end()) {
-                return constantExpressionPair->second;
+        storm::expressions::Expression Program::getInitialStatesExpression() const {
+            // If the program specifies the initial states explicitly, we simply return the expression.
+            if (this->definesInitialStatesExpression()) {
+                return this->initialStatesExpression;
             } else {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown undefined integer constant " << constantName << ".";
+                // Otherwise, we need to assert that all variables are equal to their initial value.
+                storm::expressions::Expression result = storm::expressions::Expression::createTrue();
+                
+                for (auto const& module : this->getModules()) {
+                    for (auto const& booleanVariable : module.getBooleanVariables()) {
+                        result = result && (storm::expressions::Expression::createBooleanVariable(booleanVariable.second.getName()).iff(booleanVariable.second.getInitialValueExpression()));
+                    }
+                    for (auto const& integerVariable : module.getIntegerVariables()) {
+                        result = result && (storm::expressions::Expression::createIntegerVariable(integerVariable.second.getName()) == integerVariable.second.getInitialValueExpression());
+                    }
+                }
+                return result;
             }
         }
         
-        bool Program::hasUndefinedDoubleConstant(std::string const& constantName) const {
-            return this->doubleUndefinedConstantExpressions.find(constantName) != this->doubleUndefinedConstantExpressions.end();
+        std::set<std::string> const& Program::getActions() const {
+            return this->actions;
         }
         
-        std::unique_ptr<storm::ir::expressions::DoubleConstantExpression> const& Program::getUndefinedDoubleConstantExpression(std::string const& constantName) const {
-            auto constantExpressionPair = this->doubleUndefinedConstantExpressions.find(constantName);
-            if (constantExpressionPair != this->doubleUndefinedConstantExpressions.end()) {
-                return constantExpressionPair->second;
-            } else {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown undefined double constant " << constantName << ".";
-            }
+        std::set<uint_fast64_t> const& Program::getModuleIndicesByAction(std::string const& action) const {
+            auto const& actionModuleSetPair = this->actionsToModuleIndexMap.find(action);
+            LOG_THROW(actionModuleSetPair != this->actionsToModuleIndexMap.end(), storm::exceptions::OutOfRangeException, "Action name '" << action << "' does not exist.");
+            return actionModuleSetPair->second;
         }
         
-        std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& Program::getBooleanUndefinedConstantExpressionsMap() const {
-            return this->booleanUndefinedConstantExpressions;
+        uint_fast64_t Program::getModuleIndexByVariable(std::string const& variableName) const {
+            auto const& variableNameToModuleIndexPair = this->variableToModuleIndexMap.find(variableName);
+            LOG_THROW(variableNameToModuleIndexPair != this->variableToModuleIndexMap.end(), storm::exceptions::OutOfRangeException, "Variable '" << variableName << "' does not exist.");
+            return variableNameToModuleIndexPair->second;
         }
         
-        std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& Program::getIntegerUndefinedConstantExpressionsMap() const {
-            return this->integerUndefinedConstantExpressions;
+        std::map<std::string, storm::prism::RewardModel> const& Program::getRewardModels() const {
+            return this->rewardModels;
         }
         
-        std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& Program::getDoubleUndefinedConstantExpressionsMap() const {
-            return this->doubleUndefinedConstantExpressions;
+        storm::prism::RewardModel const& Program::getRewardModel(std::string const& name) const {
+            auto const& nameRewardModelPair = this->getRewardModels().find(name);
+            LOG_THROW(nameRewardModelPair != this->getRewardModels().end(), storm::exceptions::OutOfRangeException, "Reward model '" << name << "' does not exist.");
+            return nameRewardModelPair->second;
         }
         
-        uint_fast64_t Program::getGlobalIndexOfBooleanVariable(std::string const& variableName) const {
-            return this->globalBooleanVariableToIndexMap.at(variableName);
+        std::map<std::string, storm::expressions::Expression> const& Program::getLabels() const {
+            return this->labels;
         }
         
-        uint_fast64_t Program::getGlobalIndexOfIntegerVariable(std::string const& variableName) const {
-            return this->globalIntegerVariableToIndexMap.at(variableName);
+        Program Program::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
+            std::vector<storm::prism::Module> newModules;
+            newModules.reserve(this->getNumberOfModules());
+            
+            for (auto const& module : this->getModules()) {
+                newModules.push_back(module.restrictCommands(indexSet));
+            }
+            
+            return Program(this->getModelType(), this->getUndefinedBooleanConstants(), this->getUndefinedIntegerConstants(), this->getUndefinedDoubleConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
         }
         
-        void Program::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
-            for (auto& module : modules) {
-                module.restrictCommands(indexSet);
+        std::ostream& operator<<(std::ostream& stream, Program const& program) {
+            switch (program.getModelType()) {
+                case Program::ModelType::UNDEFINED: stream << "undefined"; break;
+                case Program::ModelType::DTMC: stream << "dtmc"; break;
+                case Program::ModelType::CTMC: stream << "ctmc"; break;
+                case Program::ModelType::MDP: stream << "mdp"; break;
+                case Program::ModelType::CTMDP: stream << "ctmdp"; break;
+                case Program::ModelType::MA: stream << "ma"; break;
+            }
+            stream << std::endl;
+            
+            for (auto const& element : program.getUndefinedBooleanConstants()) {
+                stream << "const bool " << element << ";" << std::endl;
+            }
+            for (auto const& element : program.getUndefinedIntegerConstants()) {
+                stream << "const int " << element << ";" << std::endl;
             }
+            for (auto const& element : program.getUndefinedDoubleConstants()) {
+                stream << "const double " << element << ";" << std::endl;
+            }
+            stream << std::endl;
+            
+            for (auto const& element : program.getGlobalBooleanVariables()) {
+                stream << "global " << element.second << std::endl;
+            }
+            for (auto const& element : program.getGlobalIntegerVariables()) {
+                stream << "global " << element.second << std::endl;
+            }
+            stream << std::endl;
+            
+            for (auto const& module : program.getModules()) {
+                stream << module << std::endl;
+            }
+            
+            for (auto const& rewardModel : program.getRewardModels()) {
+                stream << rewardModel.second << std::endl;
+            }
+            
+            for (auto const& label : program.getLabels()) {
+                stream << "label \"" << label.first << "\" = " << label.second <<";" << std::endl;
+            }
+            
+            return stream;
         }
         
     } // namespace ir
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 172d3f3b5..3f1b54e0d 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -17,7 +17,7 @@ namespace storm {
             /*!
              * An enum for the different model types.
              */
-            enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP, MA};
+            enum class ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP, MA};
             
             /*!
              * Creates a program with the given model type, undefined constants, global variables, modules, reward
@@ -32,9 +32,9 @@ namespace storm {
              * @param modules The modules of the program.
              * @param hasInitialStatesExpression A flag indicating whether the program specifies its initial states via
              * an explicit initial construct.
-             * @param initialStatesExpression If the model specifies an explicit initial construct, this expression
-             * defines its initial states. Otherwise it is irrelevant and may be set to an arbitrary (but valid)
-             * expression, e.g. false.
+             * @param initialStatesExpression If the model specifies an explicit initial construct, this
+             * expression defines its initial states. Otherwise it is irrelevant and may be set to an arbitrary (but
+             * valid) expression, e.g. false.
              * @param rewardModels The reward models of the program.
              * @param labels The labels defined for this program.
              */
@@ -116,7 +116,7 @@ namespace storm {
              * @param variableName The name of the global boolean variable to retrieve.
              * @return The global boolean variable with the given name.
              */
-            storm::ir::BooleanVariable const& getGlobalBooleanVariable(std::string const& variableName) const;
+            storm::prism::BooleanVariable const& getGlobalBooleanVariable(std::string const& variableName) const;
             
             /*!
              * Retrieves the global integer variables of the program.
@@ -131,7 +131,7 @@ namespace storm {
              * @param variableName The name of the global integer variable to retrieve.
              * @return The global integer variable with the given name.
              */
-            storm::ir::IntegerVariable const& getGlobalIntegerVariable(std::string const& variableName) const;
+            storm::prism::IntegerVariable const& getGlobalIntegerVariable(std::string const& variableName) const;
 
             /*!
              * Retrieves the number of global boolean variables of the program.
@@ -162,6 +162,27 @@ namespace storm {
              */
             storm::prism::Module const& getModule(uint_fast64_t index) const;
             
+            /*!
+             * Retrieves all modules of the program.
+             *
+             * @return All modules of the program.
+             */
+            std::vector<storm::prism::Module> const& getModules() const;
+            
+            /*!
+             * Retrieves whether the program explicitly specifies an expression characterizing the initial states.
+             *
+             * @return True iff the program specifies an expression defining the initial states.
+             */
+            bool definesInitialStatesExpression() const;
+            
+            /*!
+             * Retrieves an expression characterizing the initial states of the program.
+             *
+             * @return An expression characterizing the initial states.
+             */
+            storm::expressions::Expression getInitialStatesExpression() const;
+            
             /*!
              * Retrieves the set of actions present in the program.
              *
@@ -206,7 +227,7 @@ namespace storm {
              *
              * @return A set of labels that are defined in the program.
              */
-            std::map<std::string, Expression> const& getLabels() const;
+            std::map<std::string, storm::expressions::Expression> const& getLabels() const;
             
             /*!
              * Creates a new program that drops all commands whose indices are not in the given set.
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index 7a4bb64ad..f08627479 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -81,7 +81,7 @@ namespace storm {
             }
             i = 0;
             for (auto const& assignment : update.getIntegerAssignments()) {
-                result << assignment.second;
+                stream << assignment.second;
                 if (i < update.getIntegerAssignments().size() - 1) {
                     stream << " & ";
                 }

From 41b31df0ab7807276370d802c8a420d3e7fdc1fc Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 7 Apr 2014 22:56:51 +0200
Subject: [PATCH 063/147] Added small tests for implies/iff in expressions.

Former-commit-id: 3d90be7596820dd0f420999fabad196edbc29cd1
---
 test/functional/storage/ExpressionTest.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index a7f789769..6563a749d 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -244,6 +244,18 @@ TEST(Expression, OperatorTest) {
     ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::maximum(intVarExpression, doubleConstExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
     
+    ASSERT_THROW(tempExpression = trueExpression.implies(piExpression), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = trueExpression.implies(falseExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.implies(boolConstExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
+    ASSERT_THROW(tempExpression = trueExpression.iff(piExpression), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = trueExpression.iff(falseExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.iff(boolConstExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
     ASSERT_THROW(tempExpression = trueExpression.floor(), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression.floor());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);

From cc0c3276681fc23daba59f5e6fe215b26aa8ecb3 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 8 Apr 2014 16:39:12 +0200
Subject: [PATCH 064/147] Removed superfluous grammars and started working on
 making one PRISM grammar to rule them all.

Former-commit-id: 375acb4699e696cb4c88f48fcb53550ddddab680
---
 src/parser/PrismParser.h                      |  60 ++---
 src/parser/prismparser/BaseGrammar.h          | 253 ------------------
 .../prismparser/BooleanExpressionGrammar.cpp  |  42 ---
 .../prismparser/BooleanExpressionGrammar.h    |  54 ----
 .../ConstBooleanExpressionGrammar.cpp         |  38 ---
 .../ConstBooleanExpressionGrammar.h           |  47 ----
 .../ConstDoubleExpressionGrammar.cpp          |  34 ---
 .../ConstDoubleExpressionGrammar.h            |  41 ---
 .../ConstIntegerExpressionGrammar.cpp         |  41 ---
 .../ConstIntegerExpressionGrammar.h           |  42 ---
 src/parser/prismparser/IdentifierGrammars.cpp |  23 --
 src/parser/prismparser/IdentifierGrammars.h   |  42 ---
 src/parser/prismparser/Includes.h             |  39 ---
 .../prismparser/IntegerExpressionGrammar.cpp  |  42 ---
 .../prismparser/IntegerExpressionGrammar.h    |  50 ----
 src/parser/prismparser/PrismGrammar.h         | 123 +++------
 src/parser/prismparser/Tokens.h               | 129 +++++----
 src/parser/prismparser/VariableState.cpp      | 191 -------------
 src/parser/prismparser/VariableState.h        | 207 --------------
 src/storage/prism/Assignment.cpp              |   4 +-
 src/storage/prism/Assignment.h                |  19 +-
 src/storage/prism/BooleanVariable.cpp         |   6 +-
 src/storage/prism/BooleanVariable.h           |  26 +-
 src/storage/prism/Command.cpp                 |   6 +-
 src/storage/prism/Command.h                   |  18 +-
 src/storage/prism/IntegerVariable.cpp         |   6 +-
 src/storage/prism/IntegerVariable.h           |  20 +-
 src/storage/prism/LocatedInformation.cpp      |  17 ++
 src/storage/prism/LocatedInformation.h        |  48 ++++
 src/storage/prism/Module.cpp                  |   8 +-
 src/storage/prism/Module.h                    |  20 +-
 src/storage/prism/Program.cpp                 |  16 +-
 src/storage/prism/Program.h                   |  53 +++-
 src/storage/prism/RewardModel.cpp             |   2 +-
 src/storage/prism/RewardModel.h               |  14 +-
 src/storage/prism/StateReward.cpp             |   2 +-
 src/storage/prism/StateReward.h               |  15 +-
 src/storage/prism/TransitionReward.cpp        |   2 +-
 src/storage/prism/TransitionReward.h          |  15 +-
 src/storage/prism/Update.cpp                  |  12 +-
 src/storage/prism/Update.h                    |  21 +-
 src/storage/prism/Variable.cpp                |   4 +-
 src/storage/prism/Variable.h                  |  11 +-
 43 files changed, 384 insertions(+), 1479 deletions(-)
 delete mode 100644 src/parser/prismparser/BaseGrammar.h
 delete mode 100644 src/parser/prismparser/BooleanExpressionGrammar.cpp
 delete mode 100644 src/parser/prismparser/BooleanExpressionGrammar.h
 delete mode 100644 src/parser/prismparser/ConstBooleanExpressionGrammar.cpp
 delete mode 100644 src/parser/prismparser/ConstBooleanExpressionGrammar.h
 delete mode 100644 src/parser/prismparser/ConstDoubleExpressionGrammar.cpp
 delete mode 100644 src/parser/prismparser/ConstDoubleExpressionGrammar.h
 delete mode 100644 src/parser/prismparser/ConstIntegerExpressionGrammar.cpp
 delete mode 100644 src/parser/prismparser/ConstIntegerExpressionGrammar.h
 delete mode 100644 src/parser/prismparser/IdentifierGrammars.cpp
 delete mode 100644 src/parser/prismparser/IdentifierGrammars.h
 delete mode 100644 src/parser/prismparser/Includes.h
 delete mode 100644 src/parser/prismparser/IntegerExpressionGrammar.cpp
 delete mode 100644 src/parser/prismparser/IntegerExpressionGrammar.h
 delete mode 100644 src/parser/prismparser/VariableState.cpp
 delete mode 100644 src/parser/prismparser/VariableState.h
 create mode 100644 src/storage/prism/LocatedInformation.cpp
 create mode 100644 src/storage/prism/LocatedInformation.h

diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index da8ad0941..49bdd20c5 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -1,49 +1,35 @@
-/* * PrismParser.h
- *
- *  Created on: Jan 3, 2013
- *      Author: Christian Dehnert
- */
-
 #ifndef STORM_PARSER_PRISMPARSER_H_
 #define STORM_PARSER_PRISMPARSER_H_
 
 // All classes of the intermediate representation are used.
-#include "src/ir/IR.h"
+#include "src/storage/prism/Program.h"
 
 // Used for file input.
 #include <istream>
-#include <memory>
 
 namespace storm {
-
-namespace parser {
-
-using namespace storm::ir;
-using namespace storm::ir::expressions;
-
-/*
- * This functions parse the format of the PRISM model checker into an intermediate representation.
- */
-
-/*!
- * Parses the given file into the intermediate representation assuming it complies with the
- * PRISM syntax.
- * @param filename the name of the file to parse.
- * @return a shared pointer to the intermediate representation of the PRISM file.
- */
-storm::ir::Program PrismParserFromFile(std::string const& filename);
-
-/*!
- * Parses the given input stream into the intermediate representation assuming it complies with
- * the PRISM syntax.
- * @param inputStream the input stream to parse.
- * @param filename the name of the file the input stream belongs to. Used for diagnostics.
- * @return a shared pointer to the intermediate representation of the PRISM file.
- */
-storm::ir::Program PrismParser(std::istream& inputStream, std::string const& filename);
-
-} // namespace parser
-
+    namespace parser {
+        using namespace storm::prism;
+        using namespace storm::expressions;
+        
+        /*!
+         * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
+         *
+         * @param filename the name of the file to parse.
+         * @return The resulting PRISM program.
+         */
+        storm::prism::Program PrismParserFromFile(std::string const& filename);
+        
+        /*!
+         * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
+         *
+         * @param inputStream The input stream to parse.
+         * @param filename The name of the file the input stream belongs to.
+         * @return The resulting PRISM program.
+         */
+        storm::prism::Program PrismParser(std::istream& inputStream, std::string const& filename);
+        
+    } // namespace parser
 } // namespace storm
 
 #endif /* STORM_PARSER_PRISMPARSER_H_ */
diff --git a/src/parser/prismparser/BaseGrammar.h b/src/parser/prismparser/BaseGrammar.h
deleted file mode 100644
index 7cac493c3..000000000
--- a/src/parser/prismparser/BaseGrammar.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/* 
- * File:   Keywords.h
- * Author: nafur
- *
- * Created on April 10, 2013, 6:03 PM
- */
-
-#ifndef BASEGRAMMAR_H
-#define	BASEGRAMMAR_H
-
-#include "Includes.h"
-
-#include "VariableState.h"
-
-namespace storm {
-namespace parser {
-namespace prism {
-
-	/*!
-	 * This is the base class for all expression grammars.
-	 * It takes care of implementing a singleton, stores a VariableState and implements some common helper routines.
-	 */
-	template <typename T>
-	class BaseGrammar {
-	public:
-		/*!
-		 * Constructor.
-		 */
-		BaseGrammar(std::shared_ptr<VariableState> const& state) : state(state) {}
-
-		/*!
-		 * Create and return a new instance of class T, usually the subclass.
-		 * @param state VariableState to be given to the constructor.
-		 * @returns Instance of class T.
-		 */
-		static T& instance(std::shared_ptr<VariableState> const& state = nullptr) {
-			if (BaseGrammar::instanceObject == nullptr) {
-				BaseGrammar::instanceObject = std::shared_ptr<T>(new T(state));
-				if (!state->firstRun) BaseGrammar::instanceObject->secondRun();
-			}
-			return *BaseGrammar::instanceObject;
-		}
-
-		/*!
-		 * Clear the cached instance.
-		 */
-		static void resetInstance() {
-			BaseGrammar::instanceObject = nullptr;
-		}
-
-		/*!
-		 * Notify the cached object, that we will begin with the second parsing run.
-		 */
-		static void secondRun() {
-			if (BaseGrammar::instanceObject != nullptr) {
-				BaseGrammar::instanceObject->prepareSecondRun();
-			}
-		}
-
-		/*!
-		 * Create a new boolean literal with the given value.
-		 * @param value Value of the literal.
-		 * @returns Boolean literal.
-		 */
-		std::shared_ptr<BaseExpression> createBoolLiteral(bool value) {
-			return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(value));
-		}
-		/*!
-		 * Create a new double literal with the given value.
-		 * @param value Value of the literal.
-		 * @returns Double literal.
-		 */
-		std::shared_ptr<BaseExpression> createDoubleLiteral(double value) {
-			return std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(value));
-		}
-		/*!
-		 * Create a new integer literal with the given value.
-		 * @param value Value of the literal.
-		 * @returns Integer literal.
-		 */
-		std::shared_ptr<BaseExpression> createIntLiteral(int_fast64_t value) {
-			return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(value));
-		}
-		
-		/*!
-		 * Create a new plus expression. If addition is true, it will be an addition, otherwise a subtraction.
-		 * @param left Left operand.
-		 * @param addition Flag for addition or subtraction.
-		 * @param right Right operand.
-		 * @param type Return type.
-		 * @returns Plus expression.
-		 */
-		std::shared_ptr<BaseExpression> createPlus(std::shared_ptr<BaseExpression> const& left, bool addition, std::shared_ptr<BaseExpression> const& right, BaseExpression::ReturnType type) {
-			if (addition) {
-				return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(type, left->clone(), right->clone(), BinaryNumericalFunctionExpression::PLUS));
-			} else {
-				return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(type, left->clone(), right->clone(), BinaryNumericalFunctionExpression::MINUS));
-			}
-		}
-		/*!
-		 * Create a new double plus expression. If addition is true, it will be an addition, otherwise a subtraction.
-		 * @param left Left operand.
-		 * @param addition Flag for addition or subtraction.
-		 * @param right Right operand.
-		 * @returns Double plus expression.
-		 */
-		std::shared_ptr<BaseExpression> createDoublePlus(std::shared_ptr<BaseExpression> const& left, bool addition, std::shared_ptr<BaseExpression> const& right) {
-			return this->createPlus(left, addition, right, BaseExpression::double_);
-		}
-		/*!
-		 * Create a new integer plus expression. If addition is true, it will be an addition, otherwise a subtraction.
-		 * @param left Left operand.
-		 * @param addition Flag for addition or subtraction.
-		 * @param right Right operand.
-		 * @returns Integer plus expression.
-		 */
-		std::shared_ptr<BaseExpression> createIntPlus(std::shared_ptr<BaseExpression> const& left, bool addition, std::shared_ptr<BaseExpression> const& right) {
-			return this->createPlus(left, addition, right, BaseExpression::int_);
-		}
-
-		/*!
-		 * Create a new integer multiplication expression.
-		 * @param left Left operand.
-		 * @param right Right operand.
-		 * @returns Integer multiplication expression.
-		 */
-		std::shared_ptr<BaseExpression> createIntMult(std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
-			return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::int_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::TIMES));
-		}
-        
-		/*!
-		 * Create a new integer multiplication expression. If multiplication is true, it will be an multiplication, otherwise a division.
-		 * @param left Left operand.
-		 * @param addition Flag for multiplication or division.
-		 * @param right Right operand.
-		 * @returns Integer multiplication expression.
-		 */
-		std::shared_ptr<BaseExpression> createDoubleMult(std::shared_ptr<BaseExpression> const& left, bool multiplication, std::shared_ptr<BaseExpression> const& right) {
-			if (multiplication) {
-				return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::double_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::TIMES));
-			} else {
-				return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::double_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::DIVIDE));
-			}
-		}
-        
-        /*!
-         * Creates an integer min/max expression.
-         *
-         * @param min Indicates whether the expression is min or max.
-         * @param left The left operand.
-         * @param right The right operand.
-         * @return An integer min/max expression.
-         */
-        std::shared_ptr<BaseExpression> createIntMinMax(bool min, std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
-            if (min) {
-                return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::int_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::MIN));
-            } else {
-                return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::int_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::MAX));
-            }
-        }
-        
-        /*!
-         * Creates an integer floor/ceil expression.
-         *
-         * @param floor Indicates whether the expression is a floor expression.
-         * @param operand The argument of the floor/ceil operation.
-         * @return An integer floor/ceil expression.
-         */
-        std::shared_ptr<BaseExpression> createIntFloorCeil(bool floor, std::shared_ptr<BaseExpression> const& operand) {
-            if (floor) {
-                return std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(BaseExpression::int_, operand->clone(), UnaryNumericalFunctionExpression::FLOOR));
-            } else {
-                return std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(BaseExpression::int_, operand->clone(), UnaryNumericalFunctionExpression::CEIL));
-            }
-        }
-        
-		/*!
-		 * Create a new binary relation expression.
-		 * @param left Left operand.
-		 * @param relationType Type of binary relation.
-		 * @param right Right operand.
-		 * @returns Binary relation expression.
-		 */
-		std::shared_ptr<BaseExpression> createRelation(std::shared_ptr<BaseExpression> const& left, BinaryRelationExpression::RelationType relationType, std::shared_ptr<BaseExpression> const& right) {
-			return std::shared_ptr<BaseExpression>(new BinaryRelationExpression(left->clone(), right->clone(), relationType));
-		}
-		/*!
-		 * Create a new negation expression.
-		 * @param child Expression to be negated.
-		 * @returns Negation expression.
-		 */
-		std::shared_ptr<BaseExpression> createNot(std::shared_ptr<BaseExpression> const& child) {
-			return std::shared_ptr<UnaryBooleanFunctionExpression>(new UnaryBooleanFunctionExpression(child->clone(), UnaryBooleanFunctionExpression::NOT));
-		}
-		/*!
-		 * Create a new And expression.
-		 * @param left Left operand.
-		 * @param right Right operand.
-		 * @returns And expression.
-		 */
-		std::shared_ptr<BaseExpression> createAnd(std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
-			return std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(left->clone(), right->clone(), BinaryBooleanFunctionExpression::AND));
-		}
-		/*!
-		 * Create a new Or expression.
-		 * @param left Left operand.
-		 * @param right Right operand.
-		 * @returns Or expression.
-		 */
-		std::shared_ptr<BaseExpression> createOr(std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
-			return std::shared_ptr<BinaryBooleanFunctionExpression>(new BinaryBooleanFunctionExpression(left->clone(), right->clone(), BinaryBooleanFunctionExpression::OR));
-		}
-		/*!
-		 * Retrieve boolean variable by name.
-		 * @param name Variable name.
-		 * @returns Boolean variable.
-		 */
-		std::shared_ptr<BaseExpression> getBoolVariable(std::string const& name) {
-			return std::shared_ptr<BaseExpression>(new VariableExpression(*state->getBooleanVariableExpression(name)));
-		}
-		/*!
-		 * Retrieve integer variable by name.
-		 * @param name Variable name.
-		 * @returns Integer variable.
-		 */
-		std::shared_ptr<BaseExpression> getIntVariable(std::string const& name) {
-			return std::shared_ptr<BaseExpression>(new VariableExpression(*state->getIntegerVariableExpression(name)));
-		}
-
-		/*!
-		 * Base method to switch to second run. This does nothing.
-		 * Any subclass that needs to do something in order to proceed to the second run should override this method.
-		 */
-		virtual void prepareSecondRun() {}
-        
-	protected:
-		/*!
-		 * Pointer to variable state.
-		 */
-		std::shared_ptr<VariableState> state;
-
-	private:
-		static std::shared_ptr<T> instanceObject;
-		static bool inSecondRun;
-	};
-
-	template <typename T>
-	std::shared_ptr<T> BaseGrammar<T>::instanceObject;
-}
-}
-}
-#endif	/* BASEGRAMMAR_H */
-
diff --git a/src/parser/prismparser/BooleanExpressionGrammar.cpp b/src/parser/prismparser/BooleanExpressionGrammar.cpp
deleted file mode 100644
index a7d9366f8..000000000
--- a/src/parser/prismparser/BooleanExpressionGrammar.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "BooleanExpressionGrammar.h"
-
-#include "IntegerExpressionGrammar.h"
-#include "ConstBooleanExpressionGrammar.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptr<VariableState> const& state)
-            : BooleanExpressionGrammar::base_type(booleanExpression), BaseGrammar(state) {
-                
-                booleanExpression %= orExpression;
-                booleanExpression.name("boolean expression");
-                
-                orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)];
-                orExpression.name("boolean expression");
-                
-                andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::bind(&BaseGrammar::createAnd, this, qi::_val, qi::_1)];
-                andExpression.name("boolean expression");
-                
-                notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::bind(&BaseGrammar::createNot, this, qi::_1)];
-                notExpression.name("boolean expression");
-                
-                atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | this->state->constantBooleanFormulas_ | this->state->booleanFormulas_ | qi::lit("(") >> booleanExpression >> qi::lit(")") | ConstBooleanExpressionGrammar::instance(this->state));
-                atomicBooleanExpression.name("boolean expression");
-                
-                relativeExpression = (IntegerExpressionGrammar::instance(this->state) >> relations_ >> IntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&BaseGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)];
-                relativeExpression.name("relative expression");
-                
-                booleanVariableExpression = IdentifierGrammar::instance(this->state)[qi::_val = phoenix::bind(&BaseGrammar::getBoolVariable, this, qi::_1)];
-                booleanVariableExpression.name("boolean variable");
-            }
-            
-            void BooleanExpressionGrammar::prepareSecondRun() {
-                booleanVariableExpression %= this->state->booleanVariables_;
-                booleanVariableExpression.name("boolean variable");
-            }
-            
-        } // namespace prism
-    } // namespace parser
-} // namespace storm
diff --git a/src/parser/prismparser/BooleanExpressionGrammar.h b/src/parser/prismparser/BooleanExpressionGrammar.h
deleted file mode 100644
index 909219fa3..000000000
--- a/src/parser/prismparser/BooleanExpressionGrammar.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 
- * File:   BooleanExpressionGrammar.h
- * Author: nafur
- *
- * Created on April 10, 2013, 6:27 PM
- */
-
-#ifndef BOOLEANEXPRESSIONGRAMMAR_H
-#define	BOOLEANEXPRESSIONGRAMMAR_H
-
-#include "Includes.h"
-#include "VariableState.h"
-#include "IdentifierGrammars.h"
-#include "Tokens.h"
-
-#include <iostream>
-
-namespace storm {
-namespace parser {
-namespace prism {
-
-/*!
- * This grammar parses (non constant) boolean expressions as used in prism models.
- */
-class BooleanExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<BooleanExpressionGrammar> {
-public:
-	BooleanExpressionGrammar(std::shared_ptr<VariableState> const& state);
-	/*!
-	 * Switch to second run.
-	 * Variable names may be any valid identifier in the first run, but only defined variables in the second run.
-	 */
-	virtual void prepareSecondRun();
-	
-private:
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> booleanExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> orExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> andExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> notExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> atomicBooleanExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> relativeExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanVariableExpression;
-
-	/*!
-	 * Parser relation operators.
-	 */
-	storm::parser::prism::relationalOperatorStruct relations_;
-};
-
-
-}
-}
-}
-
-#endif	/* BOOLEANEXPRESSIONGRAMMAR_H */
diff --git a/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp b/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp
deleted file mode 100644
index a5ce0567d..000000000
--- a/src/parser/prismparser/ConstBooleanExpressionGrammar.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "ConstBooleanExpressionGrammar.h"
-
-#include "ConstIntegerExpressionGrammar.h"
-
-namespace storm {
-namespace parser {
-namespace prism {
-
-	ConstBooleanExpressionGrammar::ConstBooleanExpressionGrammar(std::shared_ptr<VariableState> const& state)
-		: ConstBooleanExpressionGrammar::base_type(constantBooleanExpression), BaseGrammar(state) {
-
-		constantBooleanExpression %= constantOrExpression;
-		constantBooleanExpression.name("constant boolean expression");
-		
-		constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)];
-		constantOrExpression.name("constant boolean expression");
-
-		constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::bind(&BaseGrammar::createAnd, this, qi::_val, qi::_1)];
-		constantAndExpression.name("constant boolean expression");
-
-		constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::bind(&BaseGrammar::createNot, this, qi::_1)];
-		constantNotExpression.name("constant boolean expression");
-
-		constantAtomicBooleanExpression %= (constantRelativeExpression | this->state->constantBooleanFormulas_ | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression);
-		constantAtomicBooleanExpression.name("constant boolean expression");
-
-		constantRelativeExpression = (ConstIntegerExpressionGrammar::instance(this->state) >> relations_ >> ConstIntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&BaseGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)];
-		constantRelativeExpression.name("constant boolean expression");
-		
-		booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression);
-		booleanConstantExpression.name("boolean constant or literal");
-
-		booleanLiteralExpression = qi::bool_[qi::_val = phoenix::bind(&BaseGrammar::createBoolLiteral, this, qi::_1)];
-		booleanLiteralExpression.name("boolean literal");
-	}
-}
-}
-}
diff --git a/src/parser/prismparser/ConstBooleanExpressionGrammar.h b/src/parser/prismparser/ConstBooleanExpressionGrammar.h
deleted file mode 100644
index 8fea3ce95..000000000
--- a/src/parser/prismparser/ConstBooleanExpressionGrammar.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 
- * File:   ConstBooleanExpressionGrammar.h
- * Author: nafur
- *
- * Created on April 10, 2013, 6:34 PM
- */
-
-#ifndef CONSTBOOLEANEXPRESSIONGRAMMAR_H
-#define	CONSTBOOLEANEXPRESSIONGRAMMAR_H
-
-#include "Includes.h"
-#include "VariableState.h"
-#include "IdentifierGrammars.h"
-#include "Tokens.h"
-
-namespace storm {
-namespace parser {
-namespace prism {
-
-/*!
- * This grammar parses constant boolean expression as used in prism models.
- */
-class ConstBooleanExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<ConstBooleanExpressionGrammar> {
-public:
-	ConstBooleanExpressionGrammar(std::shared_ptr<VariableState> const& state);
-
-
-private:
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> constantBooleanExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantOrExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAndExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantNotExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAtomicBooleanExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantRelativeExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanConstantExpression;
-	qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanLiteralExpression;
-
-	storm::parser::prism::relationalOperatorStruct relations_;
-};
-
-
-}
-}
-}
-
-#endif	/* CONSTBOOLEANEXPRESSIONGRAMMAR_H */
-
diff --git a/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp b/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp
deleted file mode 100644
index 18cd5ae31..000000000
--- a/src/parser/prismparser/ConstDoubleExpressionGrammar.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "ConstDoubleExpressionGrammar.h"
-
-namespace storm {
-namespace parser {
-namespace prism {
-
-ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr<VariableState> const& state)
-	: ConstDoubleExpressionGrammar::base_type(constantDoubleExpression), BaseGrammar(state) {
-
-	constantDoubleExpression %= constantDoublePlusExpression;
-	constantDoubleExpression.name("constant double expression");
-
-	constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression)
-			[qi::_val = phoenix::bind(&BaseGrammar::createDoublePlus, this, qi::_val, qi::_a, qi::_1)];
-	constantDoublePlusExpression.name("constant double expression");
-
-	constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression)
-			[qi::_val = phoenix::bind(&BaseGrammar::createDoubleMult, this, qi::_val, qi::_a, qi::_1)];
-	constantDoubleMultExpression.name("constant double expression");
-
-	constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | this->state->constantDoubleFormulas_ | this->state->constantIntegerFormulas_ | doubleConstantExpression);
-	constantAtomicDoubleExpression.name("constant double expression");
-
-	doubleConstantExpression %= (this->state->doubleConstants_ | this->state->integerConstants_ | doubleLiteralExpression);
-	doubleConstantExpression.name("double constant or literal");
-
-	doubleLiteralExpression = qi::double_[qi::_val = phoenix::bind(&BaseGrammar::createDoubleLiteral, this, qi::_1)];
-	doubleLiteralExpression.name("double literal");
-}
-
-
-}
-}
-}
diff --git a/src/parser/prismparser/ConstDoubleExpressionGrammar.h b/src/parser/prismparser/ConstDoubleExpressionGrammar.h
deleted file mode 100644
index 41c503731..000000000
--- a/src/parser/prismparser/ConstDoubleExpressionGrammar.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 
- * File:   ConstDoubleExpressionGrammar.h
- * Author: nafur
- *
- * Created on April 10, 2013, 7:04 PM
- */
-
-#ifndef CONSTDOUBLEEXPRESSIONGRAMMAR_H
-#define	CONSTDOUBLEEXPRESSIONGRAMMAR_H
-
-#include "Includes.h"
-#include "VariableState.h"
-#include "IdentifierGrammars.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            /*!
-             * This grammar parses constant double expressions as used in prism models.
-             */
-            class ConstDoubleExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<ConstDoubleExpressionGrammar> {
-            public:
-                ConstDoubleExpressionGrammar(std::shared_ptr<VariableState> const& state);
-                
-            private:
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> constantDoubleExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantDoublePlusExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantDoubleMultExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAtomicDoubleExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> doubleConstantExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> doubleLiteralExpression;
-            };
-            
-            
-        }
-    }
-}
-
-#endif	/* CONSTDOUBLEEXPRESSIONGRAMMAR_H */
-
diff --git a/src/parser/prismparser/ConstIntegerExpressionGrammar.cpp b/src/parser/prismparser/ConstIntegerExpressionGrammar.cpp
deleted file mode 100644
index 9ebebebc7..000000000
--- a/src/parser/prismparser/ConstIntegerExpressionGrammar.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "ConstIntegerExpressionGrammar.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            
-            ConstIntegerExpressionGrammar::ConstIntegerExpressionGrammar(std::shared_ptr<VariableState> const& state)
-            : ConstIntegerExpressionGrammar::base_type(constantIntegerExpression), BaseGrammar(state) {
-                
-                constantIntegerExpression %= constantIntegerPlusExpression;
-                constantIntegerExpression.name("constant integer expression");
-                
-                constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)
-                [qi::_val = phoenix::bind(&BaseGrammar::createIntPlus, this, qi::_val, qi::_a, qi::_1)];
-                constantIntegerPlusExpression.name("constant integer expression");
-                
-                constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)
-                [qi::_val = phoenix::bind(&BaseGrammar::createIntMult, this, qi::_val, qi::_1)];
-                constantIntegerMultExpression.name("constant integer expression");
-                
-                constantAtomicIntegerExpression %= (constantIntegerMinMaxExpression | constantIntegerFloorCeilExpression | this->state->constantIntegerFormulas_ | qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression);
-                constantAtomicIntegerExpression.name("constant integer expression");
-                
-                constantIntegerMinMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> constantIntegerExpression >> qi::lit(",") >> constantIntegerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntMinMax, this, qi::_a, qi::_1, qi::_2)];
-                constantIntegerMinMaxExpression.name("integer min/max expression");
-                
-                constantIntegerFloorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> constantIntegerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntFloorCeil, this, qi::_a, qi::_1)];
-                constantIntegerFloorCeilExpression.name("integer floor/ceil expression");
-                
-                integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression);
-                integerConstantExpression.name("integer constant or literal");
-                
-                integerLiteralExpression = qi::int_[qi::_val = phoenix::bind(&BaseGrammar::createIntLiteral, this, qi::_1)];
-                integerLiteralExpression.name("integer literal");
-                
-            }
-            
-        } // namespace prism
-    } // namespace parser
-} // namespace storm
diff --git a/src/parser/prismparser/ConstIntegerExpressionGrammar.h b/src/parser/prismparser/ConstIntegerExpressionGrammar.h
deleted file mode 100644
index 2b6a08cae..000000000
--- a/src/parser/prismparser/ConstIntegerExpressionGrammar.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 
- * File:   ConstIntegerExpressionGrammar.h
- * Author: nafur
- *
- * Created on April 10, 2013, 6:02 PM
- */
-
-#ifndef CONSTINTEGEREXPRESSIONGRAMMAR_H
-#define	CONSTINTEGEREXPRESSIONGRAMMAR_H
-
-#include "Includes.h"
-#include "VariableState.h"
-#include "IdentifierGrammars.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            /*!
-             * This grammar parses constant integer expressions as used in prism models.
-             */
-            class ConstIntegerExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<ConstIntegerExpressionGrammar> {
-            public:
-                ConstIntegerExpressionGrammar(std::shared_ptr<VariableState> const& state);
-                
-            private:
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> constantIntegerExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantIntegerPlusExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantIntegerMultExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAtomicIntegerExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerConstantExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerLiteralExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantIntegerMinMaxExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantIntegerFloorCeilExpression;
-            };
-            
-            
-        }
-    }
-}
-
-#endif	/* CONSTINTEGEREXPRESSIONGRAMMAR_H */
diff --git a/src/parser/prismparser/IdentifierGrammars.cpp b/src/parser/prismparser/IdentifierGrammars.cpp
deleted file mode 100644
index ec6f14931..000000000
--- a/src/parser/prismparser/IdentifierGrammars.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "IdentifierGrammars.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            IdentifierGrammar::IdentifierGrammar(std::shared_ptr<VariableState> const& state)
-            : IdentifierGrammar::base_type(identifierName), BaseGrammar(state) {
-                
-                identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isIdentifier, this->state.get(), qi::_1) ];
-                identifierName.name("identifier");
-            }
-            
-            FreeIdentifierGrammar::FreeIdentifierGrammar(std::shared_ptr<VariableState> const& state)
-            : FreeIdentifierGrammar::base_type(freeIdentifierName), BaseGrammar(state) {
-                
-                freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isFreeIdentifier, this->state.get(), qi::_1) ];
-                freeIdentifierName.name("identifier");
-            }
-            
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/parser/prismparser/IdentifierGrammars.h b/src/parser/prismparser/IdentifierGrammars.h
deleted file mode 100644
index ccb14bbc1..000000000
--- a/src/parser/prismparser/IdentifierGrammars.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 
- * File:   Keywords.h
- * Author: nafur
- *
- * Created on April 10, 2013, 6:03 PM
- */
-
-#ifndef IDENTIFIERGRAMMARS_H
-#define	IDENTIFIERGRAMMARS_H
-
-#include "Includes.h"
-#include "BaseGrammar.h"
-#include "VariableState.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            /*!
-             * This grammar parses a (possibly used) identifier as used in a prism models.
-             */
-            class IdentifierGrammar : public qi::grammar<Iterator, std::string(), Skipper, Unused>, public BaseGrammar<IdentifierGrammar> {
-            public:
-                IdentifierGrammar(std::shared_ptr<VariableState> const& state);
-            private:
-                qi::rule<Iterator, std::string(), Skipper> identifierName;
-            };
-            
-            /*!
-             * This grammar parses an used identifier as used in a prism models.
-             */
-            class FreeIdentifierGrammar : public qi::grammar<Iterator, std::string(), Skipper, Unused>, public BaseGrammar<IdentifierGrammar>  {
-            public:
-                FreeIdentifierGrammar(std::shared_ptr<VariableState> const& state);
-            private:
-                qi::rule<Iterator, std::string(), Skipper> freeIdentifierName;
-            };
-        }
-    }
-}
-#endif	/* IDENTIFIERGRAMMARS_H */
-
diff --git a/src/parser/prismparser/Includes.h b/src/parser/prismparser/Includes.h
deleted file mode 100644
index 49a720dad..000000000
--- a/src/parser/prismparser/Includes.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 
- * File:   Includes
- * Author: Gereon Kremer
- *
- * Created on April 10, 2013, 4:46 PM
- */
-
-#ifndef BOOSTINCLUDES_H
-#define	BOOSTINCLUDES_H
-
-// Used for Boost spirit.
-#include <boost/typeof/typeof.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
-
-// Include headers for spirit iterators. Needed for diagnostics and input stream iteration.
-#include <boost/spirit/include/classic_position_iterator.hpp>
-#include <boost/spirit/include/support_multi_pass.hpp>
-
-namespace qi = boost::spirit::qi;
-namespace phoenix = boost::phoenix;
-
-typedef std::string::const_iterator BaseIteratorType;
-typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
-typedef PositionIteratorType Iterator;
-typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
-typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
-typedef boost::spirit::unused_type Unused;
-
-#include "src/ir/IR.h"
-using namespace storm::ir;
-using namespace storm::ir::expressions;
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
-#endif	/* BOOSTINCLUDES_H */
-
diff --git a/src/parser/prismparser/IntegerExpressionGrammar.cpp b/src/parser/prismparser/IntegerExpressionGrammar.cpp
deleted file mode 100644
index 3bcfd4d4f..000000000
--- a/src/parser/prismparser/IntegerExpressionGrammar.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "IntegerExpressionGrammar.h"
-
-#include "IdentifierGrammars.h"
-#include "ConstIntegerExpressionGrammar.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            IntegerExpressionGrammar::IntegerExpressionGrammar(std::shared_ptr<VariableState> const& state)
-            : IntegerExpressionGrammar::base_type(integerExpression), BaseGrammar(state) {
-                
-                integerExpression %= integerPlusExpression;
-                integerExpression.name("integer expression");
-                
-                integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[qi::_val = phoenix::bind(&BaseGrammar::createIntPlus, this, qi::_val, qi::_a, qi::_1)];
-                integerPlusExpression.name("integer expression");
-                
-                integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression[qi::_val = phoenix::bind(&BaseGrammar::createIntMult, this, qi::_val, qi::_1)]);
-                integerMultExpression.name("integer expression");
-                
-                atomicIntegerExpression %= (integerMinMaxExpression | integerFloorCeilExpression | this->state->constantIntegerFormulas_ | this->state->integerFormulas_ | qi::lit("(") >> integerExpression >> qi::lit(")") | integerVariableExpression | ConstIntegerExpressionGrammar::instance(this->state));
-                atomicIntegerExpression.name("integer expression");
-                
-                integerMinMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> integerExpression >> qi::lit(",") >> integerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntMinMax, this, qi::_a, qi::_1, qi::_2)];
-                integerMinMaxExpression.name("integer min/max expression");
-                
-                integerFloorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> integerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntFloorCeil, this, qi::_a, qi::_1)];
-                integerFloorCeilExpression.name("integer floor/ceil expression");
-                
-                integerVariableExpression = IdentifierGrammar::instance(this->state)[qi::_val = phoenix::bind(&BaseGrammar::getIntVariable, this, qi::_1)];
-                integerVariableExpression.name("integer variable");
-            }
-            
-            void IntegerExpressionGrammar::prepareSecondRun() {
-                integerVariableExpression %= this->state->integerVariables_;
-                integerVariableExpression.name("integer variable");
-            }
-            
-        }
-    }
-}
diff --git a/src/parser/prismparser/IntegerExpressionGrammar.h b/src/parser/prismparser/IntegerExpressionGrammar.h
deleted file mode 100644
index 7531ef36e..000000000
--- a/src/parser/prismparser/IntegerExpressionGrammar.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* 
- * File:   IntegerExpressionGrammar.h
- * Author: nafur
- *
- * Created on April 10, 2013, 4:39 PM
- */
-
-#ifndef INTEGEREXPRESSIONGRAMMAR_H
-#define	INTEGEREXPRESSIONGRAMMAR_H
-
-#include "src/ir/IR.h"
-#include "VariableState.h"
-#include "Includes.h"
-#include "IdentifierGrammars.h"
-
-#include <memory>
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            /*!
-             * This grammar parses a (non constant) integer expressions as used in prism models.
-             */
-            class IntegerExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<IntegerExpressionGrammar> {
-            public:
-                IntegerExpressionGrammar(std::shared_ptr<VariableState> const& state);
-                
-                /*!
-                 * Switch to second run.
-                 * Variable names may be any valid identifier in the first run, but only defined variables in the second run.
-                 */
-                virtual void prepareSecondRun();
-                
-            private:
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> integerExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> integerPlusExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerMultExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> atomicIntegerExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerVariableExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> integerMinMaxExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> integerFloorCeilExpression;
-            };
-            
-        }
-    }
-}
-
-#endif	/* INTEGEREXPRESSIONGRAMMAR_H */
-
diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h
index 57ba55c5b..c73420057 100644
--- a/src/parser/prismparser/PrismGrammar.h
+++ b/src/parser/prismparser/PrismGrammar.h
@@ -1,103 +1,61 @@
-/*
- * File:   PrismGrammar.h
- * Author: nafur
- *
- * Created on April 30, 2013, 5:20 PM
- */
+#ifndef STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H_
+#define	STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H_
 
-#ifndef STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H
-#define	STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H
+// Include files for file input.
+#include <istream>
+#include <memory>
+
+// Include boost spirit.
+#include <boost/typeof/typeof.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+
+// Include headers for spirit iterators. Needed for diagnostics and input stream iteration.
+#include <boost/spirit/include/classic_position_iterator.hpp>
+#include <boost/spirit/include/support_multi_pass.hpp>
+
+namespace qi = boost::spirit::qi;
+namespace phoenix = boost::phoenix;
+
+typedef std::string::const_iterator BaseIteratorType;
+typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
+typedef PositionIteratorType Iterator;
+typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
+typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
+typedef boost::spirit::unused_type Unused;
 
-// All classes of the intermediate representation are used.
-#include "src/ir/IR.h"
-#include "src/parser/prismparser/Includes.h"
 #include "src/parser/prismparser/Tokens.h"
-#include "src/parser/prismparser/IdentifierGrammars.h"
-#include "src/parser/prismparser/VariableState.h"
-#include "src/parser/prismparser/ConstBooleanExpressionGrammar.h"
-#include "src/parser/prismparser/ConstDoubleExpressionGrammar.h"
-#include "src/parser/prismparser/ConstIntegerExpressionGrammar.h"
-#include "src/parser/prismparser/BooleanExpressionGrammar.h"
-#include "src/parser/prismparser/IntegerExpressionGrammar.h"
 
-// Used for file input.
-#include <istream>
-#include <memory>
+#include "src/storage/prism/Program.h"
+#include "src/storage/expressions/Expression.h"
+using namespace storm::prism;
+using namespace storm::expressions;
 
 namespace storm {
     namespace parser {
         namespace prism {
-            
-            using namespace storm::ir;
-            using namespace storm::ir::expressions;
-            
-            struct GlobalVariableInformation {
-                std::vector<BooleanVariable> booleanVariables;
-                std::vector<IntegerVariable> integerVariables;
-                std::map<std::string, uint_fast64_t> booleanVariableToIndexMap;
-                std::map<std::string, uint_fast64_t> integerVariableToIndexMap;
-            };
-            
-            /*!
-             * The Boost spirit grammar for the PRISM language. Returns the intermediate representation of
-             * the input that complies with the PRISM syntax.
-             */
-            class PrismGrammar : public qi::grammar<
-            Iterator,
-            Program(),
-            qi::locals<
-            std::map<std::string, std::unique_ptr<BooleanConstantExpression>>,
-            std::map<std::string, std::unique_ptr<IntegerConstantExpression>>,
-            std::map<std::string, std::unique_ptr<DoubleConstantExpression>>,
-            GlobalVariableInformation,
-            std::map<std::string, RewardModel>,
-            std::map<std::string, std::unique_ptr<BaseExpression>>
-            >,
-            Skipper> {
+            class PrismGrammar : public qi::grammar<Iterator, Program(), Skipper> {
             public:
                 /*!
                  * Default constructor that creates an empty and functional grammar.
                  */
                 PrismGrammar();
                 
-                /*!
-                 * Puts all sub-grammars into the mode for performing the second run. A two-run model was chosen
-                 * because modules can involve variables that are only declared afterwards, so the first run
-                 * creates all variables and the second one tries to parse the full model.
-                 */
-                void prepareForSecondRun();
-                
-                /*!
-                 * Resets all sub-grammars, i.e. puts them into an initial state.
-                 */
-                void resetGrammars();
-                
             private:
-                
-                std::shared_ptr<storm::parser::prism::VariableState> state;
-                struct qi::symbols<char, Module> moduleMap_;
-                
                 // The starting point of the grammar.
-                qi::rule<
-                Iterator,
-                Program(),
-                qi::locals<
-				std::map<std::string, std::unique_ptr<BooleanConstantExpression>>,
-				std::map<std::string, std::unique_ptr<IntegerConstantExpression>>,
-				std::map<std::string, std::unique_ptr<DoubleConstantExpression>>,
-                GlobalVariableInformation,
-				std::map<std::string, RewardModel>,
-				std::map<std::string, std::unique_ptr<BaseExpression>>
-                >,
-                Skipper> start;
+                qi::rule<Iterator, Program(), Skipper> start;
+                
+                // Rules for model type.
                 qi::rule<Iterator, Program::ModelType(), Skipper> modelTypeDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BooleanConstantExpression>>&, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>&, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>&), Skipper> constantDefinitionList;
-                qi::rule<Iterator, std::vector<Module>(), Skipper> moduleDefinitionList;
+                
+                // Rules for global constant definitions.
+                qi::rule<Iterator, qi::unused_type(std::set<std::string>&, std::set<std::string>&, std::set<std::string>&, std::map<std::string, storm::expression::Expression>&, std::map<std::string, storm::expression::Expression>&, std::map<std::string, storm::expression::Expression>&), Skipper> constantDefinitionList;
                 
                 // Rules for global variable definitions
-                qi::rule<Iterator, qi::unused_type(GlobalVariableInformation&), Skipper> globalVariableDefinitionList;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&, std::map<std::string, IntegerVariable>), Skipper> globalVariableDefinitionList;
                 
-                // Rules for module definition.
+                // Rules for modules definition.
+                qi::rule<Iterator, std::vector<Module>(), Skipper> moduleDefinitionList;
                 qi::rule<Iterator, Module(), qi::locals<std::vector<BooleanVariable>, std::vector<IntegerVariable>, std::map<std::string, uint_fast64_t>, std::map<std::string, uint_fast64_t>>, Skipper> moduleDefinition;
                 qi::rule<Iterator, Module(), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
                 
@@ -156,6 +114,9 @@ namespace storm {
                 storm::parser::prism::modelTypeStruct modelType_;
                 storm::parser::prism::relationalOperatorStruct relations_;
                 
+                // A mapping from module names to the modules themselves so they can be looked up for renaming later.
+                struct qi::symbols<char, Module> moduleMap_;
+                
                 /*!
                  * Adds a label with the given name and expression to the given label-to-expression map.
                  *
@@ -263,5 +224,5 @@ namespace storm {
 } // namespace storm
 
 
-#endif	/* STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H */
+#endif	/* STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H_ */
 
diff --git a/src/parser/prismparser/Tokens.h b/src/parser/prismparser/Tokens.h
index bbf7e8418..bcaefce7b 100644
--- a/src/parser/prismparser/Tokens.h
+++ b/src/parser/prismparser/Tokens.h
@@ -1,75 +1,66 @@
-/* 
- * File:   Tokens.h
- * Author: nafur
- *
- * Created on April 19, 2013, 11:17 PM
- */
+#ifndef STORM_PARSER_PRISMPARSER_TOKENS_H_
+#define	STORM_PARSER_PRISMPARSER_TOKENS_H_
 
-#ifndef TOKENS_H
-#define	TOKENS_H
+#include "src/storage/expressions/Expression.h"
 
 namespace storm {
-namespace parser {
-namespace prism {
-
-	/*!
-	 * A structure mapping the textual representation of a model type to the model type
-	 * representation of the intermediate representation.
-	 */
-	struct modelTypeStruct : qi::symbols<char, Program::ModelType> {
-		modelTypeStruct() {
-			add
-				("dtmc", Program::ModelType::DTMC)
-				("ctmc", Program::ModelType::CTMC)
-				("mdp", Program::ModelType::MDP)
-				("ctmdp", Program::ModelType::CTMDP)
-			;
-		}
-	};
-
-
-	/*!
-	 * A structure defining the keywords that are not allowed to be chosen as identifiers.
-	 */
-	struct keywordsStruct : qi::symbols<char, unsigned> {
-		keywordsStruct() {
-			add
-				("dtmc", 1)
-				("ctmc", 2)
-				("mdp", 3)
-				("ctmdp", 4)
-				("const", 5)
-				("int", 6)
-				("bool", 7)
-				("module", 8)
-				("endmodule", 9)
-				("rewards", 10)
-				("endrewards", 11)
-				("true", 12)
-				("false", 13)
-			;
-		}
-	};
-	
-	/*!
-	 * A structure mapping the textual representation of a binary relation to the representation
-	 * of the intermediate representation.
-	 */
-	struct relationalOperatorStruct : qi::symbols<char, BinaryRelationExpression::RelationType> {
-		relationalOperatorStruct() {
-			add
-				("=", BinaryRelationExpression::EQUAL)
-				("!=", BinaryRelationExpression::NOT_EQUAL)
-				("<", BinaryRelationExpression::LESS)
-				("<=", BinaryRelationExpression::LESS_OR_EQUAL)
-				(">", BinaryRelationExpression::GREATER)
-				(">=", BinaryRelationExpression::GREATER_OR_EQUAL)
-			;
-		}
-	};
-}
-}
+    namespace parser {
+        namespace prism {
+            /*!
+             * A structure mapping the textual representation of a model type to the model type
+             * representation of the intermediate representation.
+             */
+            struct modelTypeStruct : qi::symbols<char, Program::ModelType> {
+                modelTypeStruct() {
+                    add
+                    ("dtmc", Program::ModelType::DTMC)
+                    ("ctmc", Program::ModelType::CTMC)
+                    ("mdp", Program::ModelType::MDP)
+                    ("ctmdp", Program::ModelType::CTMDP)
+                    ("ma", Program::ModelType::MA);
+                }
+            };
+            
+            /*!
+             * A structure defining the keywords that are not allowed to be chosen as identifiers.
+             */
+            struct keywordsStruct : qi::symbols<char, unsigned> {
+                keywordsStruct() {
+                    add
+                    ("dtmc", 1)
+                    ("ctmc", 2)
+                    ("mdp", 3)
+                    ("ctmdp", 4)
+                    ("ma", 5)
+                    ("const", 6)
+                    ("int", 7)
+                    ("bool", 8)
+                    ("module", 9)
+                    ("endmodule", 10)
+                    ("rewards", 11)
+                    ("endrewards", 12)
+                    ("true", 13)
+                    ("false", 14);
+                }
+            };
+            
+            /*!
+             * A structure mapping the textual representation of a binary relation.
+             */
+            struct relationalOperatorStruct : qi::symbols<char, BinaryRelationExpression::RelationType> {
+                relationalOperatorStruct() {
+                    add
+                    ("=", BinaryRelationExpression::RelationType::EQUAL)
+                    ("!=", BinaryRelationExpression::RelationType::NOT_EQUAL)
+                    ("<", BinaryRelationExpression::RelationType::LESS)
+                    ("<=", BinaryRelationExpression::RelationType::LESS_OR_EQUAL)
+                    (">", BinaryRelationExpression::RelationType::GREATER)
+                    (">=", BinaryRelationExpression::RelationType::GREATER_OR_EQUAL);
+                }
+            };
+        }
+    }
 }
 
-#endif	/* TOKENS_H */
+#endif	/* STORM_PARSER_PRISMPARSER_TOKENS_H_ */
 
diff --git a/src/parser/prismparser/VariableState.cpp b/src/parser/prismparser/VariableState.cpp
deleted file mode 100644
index 244a3f17e..000000000
--- a/src/parser/prismparser/VariableState.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-#include "VariableState.h"
-#include "src/exceptions/InvalidArgumentException.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            using namespace storm::ir;
-            using namespace storm::ir::expressions;
-            
-            template<typename T>
-            struct SymbolDump {
-                SymbolDump(std::ostream& out) : out(out) {}
-                void operator() (std::basic_string<char> s, T elem) {
-                    this->out << "\t" << s << " -> " << elem << std::endl;
-                }
-            private:
-                std::ostream& out;
-            };
-            template<typename T>
-            std::ostream& operator<<(std::ostream& out, qi::symbols<char, T>& symbols) {
-                out << "Dumping symbol table" << std::endl;
-                SymbolDump<T> dump(out);
-                symbols.for_each(dump);
-                return out;
-            }
-            std::ostream& operator<<(std::ostream& out, VariableState::variableNamesStruct& symbols) {
-                SymbolDump<std::string> dump(out);
-                symbols.for_each(dump);
-                return out;
-            }
-            
-            
-            VariableState::VariableState(bool firstRun)	: firstRun(firstRun), keywords(), nextLocalBooleanVariableIndex(0), nextLocalIntegerVariableIndex(0), nextGlobalBooleanVariableIndex(0), nextGlobalIntegerVariableIndex(0), nextGlobalCommandIndex(0), nextGlobalUpdateIndex(0) {
-                // Nothing to do here.
-            }
-            
-            uint_fast64_t VariableState::getNextLocalBooleanVariableIndex() const {
-                return this->nextLocalBooleanVariableIndex;
-            }
-            
-            uint_fast64_t VariableState::getNextLocalIntegerVariableIndex() const {
-                return this->nextLocalIntegerVariableIndex;
-            }
-            
-            uint_fast64_t VariableState::getNextGlobalBooleanVariableIndex() const {
-                return this->nextGlobalBooleanVariableIndex;
-            }
-            
-            uint_fast64_t VariableState::getNextGlobalIntegerVariableIndex() const {
-                return this->nextGlobalIntegerVariableIndex;
-            }
-            
-            uint_fast64_t VariableState::getNextGlobalCommandIndex() const {
-                return this->nextGlobalCommandIndex;
-            }
-            
-            uint_fast64_t VariableState::getNextGlobalUpdateIndex() const {
-                return this->nextGlobalUpdateIndex;
-            }
-            
-            uint_fast64_t VariableState::addBooleanVariable(std::string const& name) {
-                if (firstRun) {
-                    LOG4CPLUS_TRACE(logger, "Adding boolean variable " << name << " with new id " << this->nextGlobalBooleanVariableIndex << ".");
-                    this->booleanVariables_.add(name, std::shared_ptr<VariableExpression>(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextGlobalBooleanVariableIndex, name)));
-                    this->booleanVariableNames_.add(name, name);
-                    ++this->nextGlobalBooleanVariableIndex;
-                    ++this->nextLocalBooleanVariableIndex;
-                    return this->nextGlobalBooleanVariableIndex - 1;
-                } else {
-                    std::shared_ptr<VariableExpression> variableExpression = this->booleanVariables_.at(name);
-                    if (variableExpression != nullptr) {
-                        return variableExpression->getGlobalVariableIndex();
-                    } else {
-                        LOG4CPLUS_ERROR(logger, "Boolean variable " << name << " does not exist.");
-                        throw storm::exceptions::InvalidArgumentException() << "Boolean variable " << name << " does not exist.";
-                    }
-                }
-            }
-            
-            uint_fast64_t VariableState::addIntegerVariable(std::string const& name) {
-                if (firstRun) {
-                    LOG4CPLUS_TRACE(logger, "Adding integer variable " << name << " with new id " << this->nextGlobalIntegerVariableIndex << ".");
-                    this->integerVariables_.add(name, std::shared_ptr<VariableExpression>(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextGlobalIntegerVariableIndex, name)));
-                    this->integerVariableNames_.add(name, name);
-                    ++this->nextGlobalIntegerVariableIndex;
-                    ++this->nextLocalIntegerVariableIndex;
-                    return this->nextGlobalIntegerVariableIndex - 1;
-                } else {
-                    std::shared_ptr<VariableExpression> variableExpression = this->integerVariables_.at(name);
-                    if (variableExpression != nullptr) {
-                        return variableExpression->getGlobalVariableIndex();
-                    } else {
-                        LOG4CPLUS_ERROR(logger, "Integer variable " << name << " does not exist.");
-                        throw storm::exceptions::InvalidArgumentException() << "Integer variable " << name << " does not exist.";
-                    }
-                }
-            }
-            
-            std::shared_ptr<VariableExpression> VariableState::getBooleanVariableExpression(std::string const& name) const {
-                std::shared_ptr<VariableExpression> const* variableExpression = this->booleanVariables_.find(name);
-                if (variableExpression != nullptr) {
-                    return *variableExpression;
-                } else {
-                    if (firstRun) {
-                        LOG4CPLUS_TRACE(logger, "Trying to retrieve boolean variable " << name << " that was not yet created; returning dummy instead.");
-                        return std::shared_ptr<VariableExpression>(new VariableExpression(BaseExpression::bool_, name));
-                    } else {
-                        LOG4CPLUS_ERROR(logger, "Boolean variable " << name << " does not exist.");
-                        throw storm::exceptions::InvalidArgumentException() << "Boolean variable " << name << " does not exist.";
-                    }
-                }
-            }
-            
-            std::shared_ptr<VariableExpression> VariableState::getIntegerVariableExpression(std::string const& name) const {
-                std::shared_ptr<VariableExpression> const* variableExpression = this->integerVariables_.find(name);
-                if (variableExpression != nullptr) {
-                    return *variableExpression;
-                } else {
-                    if (firstRun) {
-                        LOG4CPLUS_TRACE(logger, "Trying to retrieve integer variable " << name << " that was not yet created; returning dummy instead.");
-                        return std::shared_ptr<VariableExpression>(new VariableExpression(BaseExpression::int_, name));
-                    } else {
-                        LOG4CPLUS_ERROR(logger, "Integer variable " << name << " does not exist.");
-                        throw storm::exceptions::InvalidArgumentException() << "Integer variable " << name << " does not exist.";
-                    }
-                }
-            }
-            
-            std::shared_ptr<VariableExpression> VariableState::getVariableExpression(std::string const& name) const {
-                std::shared_ptr<VariableExpression> const* variableExpression = this->integerVariables_.find(name);
-                if (variableExpression != nullptr) {
-                    return *variableExpression;
-                }
-                
-                variableExpression = this->booleanVariables_.find(name);
-                if (variableExpression != nullptr) {
-                    return *variableExpression;
-                }
-                LOG4CPLUS_ERROR(logger, "Variable " << name << " does not exist.");
-                throw storm::exceptions::InvalidArgumentException() << "Variable " << name << " does not exist.";
-            }
-            
-            void VariableState::clearLocalVariables() {
-                this->localBooleanVariables_.clear();
-                this->localIntegerVariables_.clear();
-                this->nextLocalBooleanVariableIndex = 0;
-                this->nextLocalIntegerVariableIndex = 0;
-            }
-            
-            bool VariableState::isFreeIdentifier(std::string const& identifier) const {
-            	if (this->booleanVariableNames_.find(identifier) != nullptr) return false;
-                if (this->integerVariableNames_.find(identifier) != nullptr) return false;
-                if (this->allConstantNames_.find(identifier) != nullptr) return false;
-                if (this->labelNames_.find(identifier) != nullptr) return false;
-                if (this->moduleNames_.find(identifier) != nullptr) return false;
-                if (this->keywords.find(identifier) != nullptr) return false;
-                if (this->booleanFormulas_.find(identifier) != nullptr) return false;
-                if (this->integerFormulas_.find(identifier) != nullptr) return false;
-                if (this->doubleFormulas_.find(identifier) != nullptr) return false;
-                if (this->constantBooleanFormulas_.find(identifier) != nullptr) return false;
-                if (this->constantIntegerFormulas_.find(identifier) != nullptr) return false;
-                if (this->constantDoubleFormulas_.find(identifier) != nullptr) return false;
-                return true;
-            }
-            
-            bool VariableState::isIdentifier(std::string const& identifier) const {
-                if (this->allConstantNames_.find(identifier) != nullptr) return false;
-                if (this->keywords.find(identifier) != nullptr) return false;
-                return true;
-            }
-            
-            void VariableState::prepareForSecondRun() {
-                integerConstants_.clear();
-                booleanConstants_.clear();
-                doubleConstants_.clear();
-                allConstantNames_.clear();
-                constantBooleanFormulas_.clear();
-                booleanFormulas_.clear();
-                constantIntegerFormulas_.clear();
-                integerFormulas_.clear();
-                constantDoubleFormulas_.clear();
-                doubleFormulas_.clear();
-                this->firstRun = false;
-                nextGlobalCommandIndex = 0;
-                nextGlobalUpdateIndex = 0;
-            }
-            
-        } // namespace prism
-    } // namespace parser
-} // namespace storm
diff --git a/src/parser/prismparser/VariableState.h b/src/parser/prismparser/VariableState.h
deleted file mode 100644
index 6dc7170a4..000000000
--- a/src/parser/prismparser/VariableState.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * File:   VariableState.h
- * Author: nafur
- *
- * Created on April 10, 2013, 4:43 PM
- */
-
-#ifndef STORM_PARSER_PRISMPARSER_VARIABLESTATE_H
-#define	STORM_PARSER_PRISMPARSER_VARIABLESTATE_H
-
-#include <iostream>
-
-#include "src/ir/IR.h"
-#include "Includes.h"
-#include "Tokens.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            
-            using namespace storm::ir;
-            using namespace storm::ir::expressions;
-            
-            template<typename T>
-            std::ostream& operator<<(std::ostream& out, qi::symbols<char, T>& symbols);
-            
-            /*!
-             * This class contains the internal state that is needed for parsing a PRISM model.
-             */
-            class VariableState {
-            public:
-                /*!
-                 * Creates a new variable state object. By default, this object will be set to a state in which
-                 * it is ready for performing a first run on some input. The first run creates all variables
-                 * while the second one checks for the correct usage of variables in expressions.
-                 *
-                 * @param firstRun If set, this object will be in a state ready for performing the first run. If
-                 * set to false, this object will assume that it has all variable data already.
-                 */
-                VariableState(bool firstRun = true);
-                
-                /*!
-                 * Indicator, if we are still in the first run.
-                 */
-                bool firstRun;
-                
-                /*!
-                 * A parser for all reserved keywords.
-                 */
-                keywordsStruct keywords;
-                
-                /*!
-                 * Internal counter for the local index of the next new boolean variable.
-                 */
-                uint_fast64_t nextLocalBooleanVariableIndex;
-                
-                /*!
-                 * Retrieves the next free local index for a boolean variable.
-                 *
-                 * @return The next free local index for a boolean variable.
-                 */
-                uint_fast64_t getNextLocalBooleanVariableIndex() const;
-                
-                /*!
-                 * Internal counter for the local index of the next new integer variable.
-                 */
-                uint_fast64_t nextLocalIntegerVariableIndex;
-                
-                /*!
-                 * Retrieves the next free global index for a integer variable.
-                 *
-                 * @return The next free global index for a integer variable.
-                 */
-                uint_fast64_t getNextLocalIntegerVariableIndex() const;
-                
-                /*!
-                 * Internal counter for the index of the next new boolean variable.
-                 */
-                uint_fast64_t nextGlobalBooleanVariableIndex;
-                
-                /*!
-                 * Retrieves the next free global index for a boolean variable.
-                 *
-                 * @return The next free global index for a boolean variable.
-                 */
-                uint_fast64_t getNextGlobalBooleanVariableIndex() const;
-                
-                /*!
-                 * Internal counter for the index of the next new integer variable.
-                 */
-                uint_fast64_t nextGlobalIntegerVariableIndex;
-                
-                /*!
-                 * Retrieves the next free global index for a integer variable.
-                 *
-                 * @return The next free global index for a integer variable.
-                 */
-                uint_fast64_t getNextGlobalIntegerVariableIndex() const;
-                
-                /*!
-                 * Internal counter for the index of the next command.
-                 */
-                uint_fast64_t nextGlobalCommandIndex;
-                
-                /*!
-                 * Retrieves the next free global index for a command.
-                 *
-                 * @return The next free global index for a command.
-                 */
-                uint_fast64_t getNextGlobalCommandIndex() const;
-                
-                /*!
-                 * Internal counter for the index of the next update.
-                 */
-                uint_fast64_t nextGlobalUpdateIndex;
-                
-                /*!
-                 * Retrieves the next free global index for an update.
-                 *
-                 * @return The next free global index for an update.
-                 */
-                uint_fast64_t getNextGlobalUpdateIndex() const;
-                
-                // Structures mapping variable and constant names to the corresponding expression nodes of
-                // the intermediate representation.
-                struct qi::symbols<char, std::shared_ptr<VariableExpression>> integerVariables_, booleanVariables_;
-                struct qi::symbols<char, std::shared_ptr<BaseExpression>> integerConstants_, booleanConstants_, doubleConstants_, booleanFormulas_, constantBooleanFormulas_, integerFormulas_, constantIntegerFormulas_, doubleFormulas_, constantDoubleFormulas_;
-                
-                // A structure representing the identity function over identifier names.
-                struct variableNamesStruct : qi::symbols<char, std::string> { }
-                integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_,
-                localBooleanVariables_, localIntegerVariables_, assignedBooleanVariables_, assignedIntegerVariables_,
-                globalBooleanVariables_, globalIntegerVariables_;
-                
-                /*!
-                 * Adds a new boolean variable with the given name.
-                 *
-                 * @param name The name of the variable.
-                 * @return The global index of the variable.
-                 */
-                uint_fast64_t addBooleanVariable(std::string const& name);
-                
-                /*!
-                 * Adds a new integer variable with the given name.
-                 *
-                 * @param name The name of the variable.
-                 * @return The global index of the variable.
-                 */
-                uint_fast64_t addIntegerVariable(std::string const& name);
-                
-                /*!
-                 * Retrieves the variable expression for the boolean variable with the given name.
-                 *
-                 * @param name The name of the boolean variable for which to retrieve the variable expression.
-                 * @return The variable expression for the boolean variable with the given name.
-                 */
-                std::shared_ptr<VariableExpression> getBooleanVariableExpression(std::string const& name) const;
-                
-                /*!
-                 * Retrieves the variable expression for the integer variable with the given name.
-                 *
-                 * @param name The name of the integer variable for which to retrieve the variable expression.
-                 * @return The variable expression for the integer variable with the given name.
-                 */
-                std::shared_ptr<VariableExpression> getIntegerVariableExpression(std::string const& name) const;
-                
-                /*!
-                 * Retrieve the variable expression for the variable with the given name.
-                 *
-                 * @param name The name of the variable for which to retrieve the variable expression.
-                 * @return The variable expression for the variable with the given name.
-                 */
-                std::shared_ptr<VariableExpression> getVariableExpression(std::string const& name) const;
-                
-                /*!
-                 * Clears all local variables.
-                 */
-                void clearLocalVariables();
-                
-                /*!
-                 * Check if the given string is a free identifier.
-                 *
-                 * @param identifier A string to be checked.
-                 * @return True iff the given string is a free identifier.
-                 */
-                bool isFreeIdentifier(std::string const& identifier) const;
-                
-                /*!
-                 * Check if given string is a valid identifier.
-                 *
-                 * @param identifier A string to be checked.
-                 * @return True iff the given string is an identifier.
-                 */
-                bool isIdentifier(std::string const& identifier) const;
-                
-                /*!
-                 * Prepare state to proceed to second parser run. Currently, this clears the constants.
-                 */
-                void prepareForSecondRun();
-            };
-            
-        } // namespace prism
-    } // namespace parser
-} // namespace storm
-
-#endif	/* STORM_PARSER_PRISMPARSER_VARIABLESTATE_H */
-
diff --git a/src/storage/prism/Assignment.cpp b/src/storage/prism/Assignment.cpp
index 4455ec65d..2c639a535 100644
--- a/src/storage/prism/Assignment.cpp
+++ b/src/storage/prism/Assignment.cpp
@@ -2,11 +2,11 @@
 
 namespace storm {
     namespace prism {
-        Assignment::Assignment(std::string const& variableName, storm::expressions::Expression const& expression) : variableName(variableName), expression(expression) {
+        Assignment::Assignment(std::string const& variableName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(variableName), expression(expression) {
             // Intentionally left empty.
         }
         
-        Assignment::Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming) : variableName(oldAssignment.getVariableName()), expression(oldAssignment.getExpression().substitute<std::map>(renaming)) {
+        Assignment::Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(oldAssignment.getVariableName()), expression(oldAssignment.getExpression().substitute<std::map>(renaming)) {
             auto renamingPair = renaming.find(oldAssignment.variableName);
             if (renamingPair != renaming.end()) {
                 this->variableName = renamingPair->second;
diff --git a/src/storage/prism/Assignment.h b/src/storage/prism/Assignment.h
index 48a235c8a..955c8417e 100644
--- a/src/storage/prism/Assignment.h
+++ b/src/storage/prism/Assignment.h
@@ -3,34 +3,39 @@
 
 #include <map>
 
+#include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace prism {
-        class Assignment {
+        class Assignment : public LocatedInformation {
         public:
             /*!
              * Constructs an assignment using the given variable name and expression.
              *
              * @param variableName The variable that this assignment targets.
              * @param expression The expression to assign to the variable.
+             * @param filename The filename in which the assignment is defined.
+             * @param lineNumber The line number in which the assignment is defined.
              */
-            Assignment(std::string const& variableName, storm::expressions::Expression const& expression);
+            Assignment(std::string const& variableName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given assignment and performs the provided renaming.
              *
              * @param oldAssignment The assignment to copy.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             * @param filename The filename in which the assignment is defined.
+             * @param lineNumber The line number in which the assignment is defined.
              */
-            Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming);
+            Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Assignment() = default;
-            Assignment(Assignment const& otherVariable) = default;
-            Assignment& operator=(Assignment const& otherVariable)= default;
-            Assignment(Assignment&& otherVariable) = default;
-            Assignment& operator=(Assignment&& otherVariable) = default;
+            Assignment(Assignment const& other) = default;
+            Assignment& operator=(Assignment const& other)= default;
+            Assignment(Assignment&& other) = default;
+            Assignment& operator=(Assignment&& other) = default;
             
             /*!
              * Retrieves the name of the variable that this assignment targets.
diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
index 39ea86304..0ce68d34d 100644
--- a/src/storage/prism/BooleanVariable.cpp
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -2,15 +2,15 @@
 
 namespace storm {
     namespace prism {
-        BooleanVariable::BooleanVariable(std::string const& variableName) : Variable(variableName, storm::expressions::Expression::createFalse(), true) {
+        BooleanVariable::BooleanVariable(std::string const& variableName, std::string const& filename, uint_fast64_t lineNumber) : Variable(variableName, storm::expressions::Expression::createFalse(), true, filename, lineNumber) {
             // Nothing to do here.
         }
 
-        BooleanVariable::BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression, false) {
+        BooleanVariable::BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(variableName, initialValueExpression, false, filename, lineNumber) {
             // Nothing to do here.
         }
         
-        BooleanVariable::BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : Variable(oldVariable, newName, renaming) {
+        BooleanVariable::BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : Variable(oldVariable, newName, renaming, filename, lineNumber) {
             // Nothing to do here.
         }
         
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
index 74c046e00..580a6c33a 100644
--- a/src/storage/prism/BooleanVariable.h
+++ b/src/storage/prism/BooleanVariable.h
@@ -11,26 +11,30 @@ namespace storm {
         public:
             // Create default implementations of constructors/assignment.
             BooleanVariable() = default;
-            BooleanVariable(BooleanVariable const& otherVariable) = default;
-            BooleanVariable& operator=(BooleanVariable const& otherVariable)= default;
-            BooleanVariable(BooleanVariable&& otherVariable) = default;
-            BooleanVariable& operator=(BooleanVariable&& otherVariable) = default;
-            
+            BooleanVariable(BooleanVariable const& other) = default;
+            BooleanVariable& operator=(BooleanVariable const& other)= default;
+            BooleanVariable(BooleanVariable&& other) = default;
+            BooleanVariable& operator=(BooleanVariable&& other) = default;
+
             /*!
-             * Creates a boolean variable with the given name and default initial value.
+             * Creates a boolean variable with the given name and the default initial value expression.
              *
              * @param variableName The name of the variable.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            BooleanVariable(std::string const& variableName);
+            BooleanVariable(std::string const& variableName, std::string const& filename, uint_fast64_t lineNumber);
 
             /*!
              * Creates a boolean variable with the given name and the given constant initial value expression.
              *
              * @param variableName The name of the variable.
              * @param initialValueExpression The constant expression that defines the initial value of the variable.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression);
-
+            BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber);
+            
             /*!
              * Creates a copy of the given boolean variable and performs the provided renaming.
              *
@@ -38,8 +42,10 @@ namespace storm {
              * @param newName New name of this variable.
              * @param renaming A mapping from names that are to be renamed to the names they are to be
              * replaced with.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming);
+            BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber);
             
             friend std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable);
         };
diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index 5624eafdb..038884593 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -2,18 +2,18 @@
 
 namespace storm {
     namespace prism {
-        Command::Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates) : actionName(actionName), guardExpression(guardExpression), updates(updates), globalIndex(globalIndex) {
+        Command::Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), actionName(actionName), guardExpression(guardExpression), updates(updates), globalIndex(globalIndex) {
             // Nothing to do here.
         }
         
-        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming) : actionName(oldCommand.getActionName()), guardExpression(oldCommand.getGuardExpression().substitute<std::map>(renaming)), globalIndex(newGlobalIndex) {
+        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), actionName(oldCommand.getActionName()), guardExpression(oldCommand.getGuardExpression().substitute<std::map>(renaming)), globalIndex(newGlobalIndex) {
             auto const& namePair = renaming.find(this->actionName);
             if (namePair != renaming.end()) {
                 this->actionName = namePair->second;
             }
             this->updates.reserve(oldCommand.getNumberOfUpdates());
             for (Update const& update : oldCommand.getUpdates()) {
-                this->updates.emplace_back(update, update.getGlobalIndex(), renaming);
+                this->updates.emplace_back(update, update.getGlobalIndex(), renaming, filename, lineNumber);
             }
         }
 
diff --git a/src/storage/prism/Command.h b/src/storage/prism/Command.h
index 8cb905346..5780c3dce 100644
--- a/src/storage/prism/Command.h
+++ b/src/storage/prism/Command.h
@@ -10,7 +10,7 @@
 
 namespace storm {
     namespace prism {
-        class Command {
+        class Command : public LocatedInformation {
         public:
             /*!
              * Creates a command with the given action name, guard and updates.
@@ -19,8 +19,10 @@ namespace storm {
              * @param actionName The action name of the command.
              * @param guardExpression the expression that defines the guard of the command.
              * @param updates A list of updates that is associated with this command.
+             * @param filename The filename in which the command is defined.
+             * @param lineNumber The line number in which the command is defined.
              */
-            Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates);
+            Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given command and performs the provided renaming.
@@ -28,15 +30,17 @@ namespace storm {
              * @param oldCommand The command to copy.
              * @param newGlobalIndex The global index of the copy of the command.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             * @param filename The filename in which the command is defined.
+             * @param lineNumber The line number in which the command is defined.
              */
-            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming);
+            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Command() = default;
-            Command(Command const& otherVariable) = default;
-            Command& operator=(Command const& otherVariable)= default;
-            Command(Command&& otherVariable) = default;
-            Command& operator=(Command&& otherVariable) = default;
+            Command(Command const& other) = default;
+            Command& operator=(Command const& other)= default;
+            Command(Command&& other) = default;
+            Command& operator=(Command&& other) = default;
             
             /*!
              * Retrieves the action name of this command.
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index 10a3f3e88..47005e6cd 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -2,15 +2,15 @@
 
 namespace storm {
     namespace prism {
-        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression) : Variable(variableName, lowerBoundExpression, true), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
+        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(variableName, lowerBoundExpression, true, filename, lineNumber), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
             // Intentionally left empty.
         }
 
-        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression) : Variable(variableName, initialValueExpression, false), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
+        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(variableName, initialValueExpression, false, filename, lineNumber), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
             // Intentionally left empty.
         }
         
-        IntegerVariable::IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : Variable(oldVariable, newName, renaming), lowerBoundExpression(oldVariable.getLowerBoundExpression().substitute<std::map>(renaming)), upperBoundExpression(oldVariable.getUpperBoundExpression().substitute<std::map>(renaming)) {
+        IntegerVariable::IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : Variable(oldVariable, newName, renaming, filename, lineNumber), lowerBoundExpression(oldVariable.getLowerBoundExpression().substitute<std::map>(renaming)), upperBoundExpression(oldVariable.getUpperBoundExpression().substitute<std::map>(renaming)) {
             // Intentionally left empty.
         }
         
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
index b2dbb4cb5..919bab480 100644
--- a/src/storage/prism/IntegerVariable.h
+++ b/src/storage/prism/IntegerVariable.h
@@ -11,10 +11,10 @@ namespace storm {
         public:
             // Create default implementations of constructors/assignment.
             IntegerVariable() = default;
-            IntegerVariable(IntegerVariable const& otherVariable) = default;
-            IntegerVariable& operator=(IntegerVariable const& otherVariable)= default;
-            IntegerVariable(IntegerVariable&& otherVariable) = default;
-            IntegerVariable& operator=(IntegerVariable&& otherVariable) = default;
+            IntegerVariable(IntegerVariable const& other) = default;
+            IntegerVariable& operator=(IntegerVariable const& other)= default;
+            IntegerVariable(IntegerVariable&& other) = default;
+            IntegerVariable& operator=(IntegerVariable&& other) = default;
 
             /*!
              * Creates an integer variable with the given name and a default initial value.
@@ -22,8 +22,10 @@ namespace storm {
              * @param variableName The name of the variable.
              * @param lowerBoundExpression A constant expression defining the lower bound of the domain of the variable.
              * @param upperBoundExpression A constant expression defining the upper bound of the domain of the variable.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression);
+            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
 
             /*!
              * Creates an integer variable with the given name and the given initial value expression.
@@ -32,8 +34,10 @@ namespace storm {
              * @param lowerBoundExpression A constant expression defining the lower bound of the domain of the variable.
              * @param upperBoundExpression A constant expression defining the upper bound of the domain of the variable.
              * @param initialValueExpression A constant expression that defines the initial value of the variable.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression);
+            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given integer variable and performs the provided renaming.
@@ -41,8 +45,10 @@ namespace storm {
              * @param oldVariable The variable to copy.
              * @param newName New name of this variable.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming);
+            IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Retrieves an expression defining the lower bound for this integer variable.
diff --git a/src/storage/prism/LocatedInformation.cpp b/src/storage/prism/LocatedInformation.cpp
new file mode 100644
index 000000000..94d965e94
--- /dev/null
+++ b/src/storage/prism/LocatedInformation.cpp
@@ -0,0 +1,17 @@
+#include "src/storage/prism/LocatedInformation.h"
+
+namespace storm {
+    namespace prism {
+        LocatedInformation::LocatedInformation(std::string const& filename, uint_fast64_t lineNumber) : filename(filename), lineNumber(lineNumber) {
+            // Intentionally left empty.
+        }
+
+        std::string const& LocatedInformation::getFilename() const {
+            return this->filename;
+        }
+        
+        uint_fast64_t LocatedInformation::getLineNumber() const {
+            return this->lineNumber;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/prism/LocatedInformation.h b/src/storage/prism/LocatedInformation.h
new file mode 100644
index 000000000..f86060958
--- /dev/null
+++ b/src/storage/prism/LocatedInformation.h
@@ -0,0 +1,48 @@
+#ifndef STORM_STORAGE_PRISM_LOCATEDINFORMATION_H_
+#define STORM_STORAGE_PRISM_LOCATEDINFORMATION_H_
+
+#include <string>
+
+namespace storm {
+    namespace prism {
+        class LocatedInformation {
+        public:
+            /*!
+             * Constructs a located information with the given filename and line number.
+             *
+             * @param filename The file in which the information was found.
+             * @param lineNumber The line number in which the information was found.
+             */
+            LocatedInformation(std::string const& filename, uint_fast64_t lineNumber);
+            
+            // Create default implementations of constructors/assignment.
+            LocatedInformation(LocatedInformation const& other) = default;
+            LocatedInformation& operator=(LocatedInformation const& other)= default;
+            LocatedInformation(LocatedInformation&& other) = default;
+            LocatedInformation& operator=(LocatedInformation&& other) = default;
+            
+            /*!
+             * Retrieves the name of the file in which the information was found.
+             *
+             * @return The name of the file in which the information was found.
+             */
+            std::string const& getFilename() const;
+            
+            /*!
+             * Retrieves the line number in which the information was found.
+             *
+             * @return The line number in which the information was found.
+             */
+            uint_fast64_t getLineNumber() const;
+
+        private:
+            // The file in which the piece of information was found.
+            std::string filename;
+            
+            // The line in the file in which the piece of information was found.
+            uint_fast64_t lineNumber;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_PRISM_LOCATEDINFORMATION_H_ */
\ No newline at end of file
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 5a90c4bda..78f561734 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -5,24 +5,24 @@
 
 namespace storm {
     namespace prism {
-        Module::Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands) : moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands), actions(), actionsToCommandIndexMap() {
+        Module::Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands), actions(), actionsToCommandIndexMap() {
             // Initialize the internal mappings for fast information retrieval.
             this->collectActions();
         }
         
-        Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming) : moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
+        Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
             // Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception is thrown.
             for (auto const& nameVariablePair : oldModule.getBooleanVariables()) {
                 auto renamingPair = renaming.find(nameVariablePair.first);
                 LOG_THROW(renamingPair == renaming.end(), storm::exceptions::InvalidArgumentException, "Boolean variable " << moduleName << "." << nameVariablePair.first << " was not renamed.");
-                this->booleanVariables.emplace(nameVariablePair.first, BooleanVariable(nameVariablePair.second, renamingPair->second, renaming));
+                this->booleanVariables.emplace(nameVariablePair.first, BooleanVariable(nameVariablePair.second, renamingPair->second, renaming, filename, lineNumber));
             }
             
             // Now do the same for the integer variables.
             for (auto const& nameVariablePair : oldModule.getIntegerVariables()) {
                 auto renamingPair = renaming.find(nameVariablePair.first);
                 LOG_THROW(renamingPair == renaming.end(), storm::exceptions::InvalidArgumentException, "Integer variable " << moduleName << "." << nameVariablePair.first << " was not renamed.");
-                this->integerVariables.emplace(nameVariablePair.first, IntegerVariable(nameVariablePair.second, renamingPair->second, renaming));
+                this->integerVariables.emplace(nameVariablePair.first, IntegerVariable(nameVariablePair.second, renamingPair->second, renaming, filename, lineNumber));
             }
             
             // Now we are ready to clone all commands and rename them if requested.
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index 789cd0e09..d8f75d13b 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -14,7 +14,7 @@
 
 namespace storm {
     namespace prism {
-        class Module {
+        class Module : public LocatedInformation {
         public:
             /*!
              * Creates a module with the given name, variables and commands.
@@ -23,10 +23,10 @@ namespace storm {
              * @param booleanVariables The boolean variables defined by the module.
              * @param integerVariables The integer variables defined by the module.
              * @param commands The commands of the module.
+             * @param filename The filename in which the module is defined.
+             * @param lineNumber The line number in which the module is defined.
              */
-            Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables,
-                   std::map<std::string, storm::prism::IntegerVariable> const& integerVariables,
-                   std::vector<storm::prism::Command> const& commands);
+            Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Special copy constructor, implementing the module renaming functionality. This will create a new module
@@ -35,15 +35,17 @@ namespace storm {
              * @param oldModule The module to be copied.
              * @param newModuleName The name of the new module.
              * @param renaming A mapping of identifiers to the new identifiers they are to be replaced with.
+             * @param filename The filename in which the module is defined.
+             * @param lineNumber The line number in which the module is defined.
              */
-            Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming);
+            Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Module() = default;
-            Module(Module const& otherVariable) = default;
-            Module& operator=(Module const& otherVariable)= default;
-            Module(Module&& otherVariable) = default;
-            Module& operator=(Module&& otherVariable) = default;
+            Module(Module const& other) = default;
+            Module& operator=(Module const& other)= default;
+            Module(Module&& other) = default;
+            Module& operator=(Module&& other) = default;
             
             /*!
              * Retrieves the number of boolean variables in the module.
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index a688a63dd..c01e24c0d 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace prism {
-        Program::Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels) : modelType(modelType), undefinedBooleanConstants(undefinedBooleanConstants), undefinedIntegerConstants(undefinedIntegerConstants), undefinedDoubleConstants(undefinedDoubleConstants), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables), modules(modules), rewardModels(rewardModels), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+        Program::Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), undefinedBooleanConstants(undefinedBooleanConstants), definedBooleanConstants(definedBooleanConstants), undefinedIntegerConstants(undefinedIntegerConstants), definedIntegerConstants(definedIntegerConstants), undefinedDoubleConstants(undefinedDoubleConstants), definedDoubleConstants(definedDoubleConstants), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables), modules(modules), rewardModels(rewardModels), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
             // Now build the mapping from action names to module indices so that the lookup can later be performed quickly.
             for (unsigned int moduleIndex = 0; moduleIndex < this->getNumberOfModules(); moduleIndex++) {
                 Module const& module = this->getModule(moduleIndex);
@@ -52,15 +52,27 @@ namespace storm {
         std::set<std::string> const& Program::getUndefinedBooleanConstants() const {
             return this->undefinedBooleanConstants;
         }
+        
+        std::map<std::string, storm::expressions::Expression> const& Program::getDefinedBooleanConstants() const {
+            return this->definedBooleanConstants;
+        }
 
         std::set<std::string> const& Program::getUndefinedIntegerConstants() const {
             return this->undefinedIntegerConstants;
         }
         
+        std::map<std::string, storm::expressions::Expression> const& Program::getDefinedIntegerConstants() const {
+            return this->definedIntegerConstants;
+        }
+
         std::set<std::string> const& Program::getUndefinedDoubleConstants() const {
             return this->undefinedDoubleConstants;
         }
-        
+
+        std::map<std::string, storm::expressions::Expression> const& Program::getDefinedDoubleConstants() const {
+            return this->definedDoubleConstants;
+        }
+
         std::map<std::string, storm::prism::BooleanVariable> const& Program::getGlobalBooleanVariables() const {
             return this->globalBooleanVariables;
         }
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 3f1b54e0d..36326b12b 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -12,7 +12,7 @@
 
 namespace storm {
     namespace prism {
-        class Program {
+        class Program : public LocatedInformation {
         public:
             /*!
              * An enum for the different model types.
@@ -25,8 +25,11 @@ namespace storm {
              *
              * @param modelType The type of the program.
              * @param undefinedBooleanConstants The undefined boolean constants of the program.
+             * @param definedBooleanConstants The defined boolean constants of the program.
              * @param undefinedIntegerConstants The undefined integer constants of the program.
+             * @param definedIntegerConstants The defined integer constants of the program.
              * @param undefinedDoubleConstants The undefined double constants of the program.
+             * @param definedDoubleConstants The defined double constants of the program.
              * @param globalBooleanVariables The global boolean variables of the program.
              * @param globalIntegerVariables The global integer variables of the program.
              * @param modules The modules of the program.
@@ -37,15 +40,17 @@ namespace storm {
              * valid) expression, e.g. false.
              * @param rewardModels The reward models of the program.
              * @param labels The labels defined for this program.
+             * @param filename The filename in which the program is defined.
+             * @param lineNumber The line number in which the program is defined.
              */
-            Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels);
+            Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Provide default implementations for constructors and assignments.
             Program() = default;
-            Program(Program const& otherProgram) = default;
-            Program& operator=(Program const& otherProgram) = default;
-            Program(Program&& otherProgram) = default;
-            Program& operator=(Program&& otherProgram) = default;
+            Program(Program const& other) = default;
+            Program& operator=(Program const& other) = default;
+            Program(Program&& other) = default;
+            Program& operator=(Program&& other) = default;
             
             /*!
              * Retrieves the model type of the model.
@@ -89,6 +94,13 @@ namespace storm {
              */
             std::set<std::string> const& getUndefinedBooleanConstants() const;
             
+            /*!
+             * Retrieves the defined boolean constants of the program.
+             *
+             * @return The defined boolean constants of the program.
+             */
+            std::map<std::string, storm::expressions::Expression> const& getDefinedBooleanConstants() const;
+            
             /*!
              * Retrieves the undefined integer constants of the program.
              *
@@ -96,6 +108,13 @@ namespace storm {
              */
             std::set<std::string> const& getUndefinedIntegerConstants() const;
 
+            /*!
+             * Retrieves the defined integer constants of the program.
+             *
+             * @return The defined integer constants of the program.
+             */
+            std::map<std::string, storm::expressions::Expression> const& getDefinedIntegerConstants() const;
+
             /*!
              * Retrieves the undefined double constants of the program.
              *
@@ -103,6 +122,13 @@ namespace storm {
              */
             std::set<std::string> const& getUndefinedDoubleConstants() const;
             
+            /*!
+             * Retrieves the defined double constants of the program.
+             *
+             * @return The defined double constants of the program.
+             */
+            std::map<std::string, storm::expressions::Expression> const& getDefinedDoubleConstants() const;
+
             /*!
              * Retrieves the global boolean variables of the program.
              *
@@ -242,15 +268,24 @@ namespace storm {
             // The type of the model.
             ModelType modelType;
             
-            // A list of undefined boolean constants of the model.
+            // The undefined boolean constants of the program.
             std::set<std::string> undefinedBooleanConstants;
             
-            // A list of undefined integer constants of the model.
+            // A mapping of (defined) boolean constants to their values (given as expressions).
+            std::map<std::string, storm::expressions::Expression> definedBooleanConstants;
+
+            // The undefined integer constants of the program.
             std::set<std::string> undefinedIntegerConstants;
 
-            // A list of undefined double constants of the model.
+            // A mapping of (defined) integer constants to their values (given as expressions).
+            std::map<std::string, storm::expressions::Expression> definedIntegerConstants;
+
+            // The undefined double constants of the program.
             std::set<std::string> undefinedDoubleConstants;
             
+            // A mapping of (defined) double constants to their values (given as expressions).
+            std::map<std::string, storm::expressions::Expression> definedDoubleConstants;
+
             // A list of global boolean variables.
             std::map<std::string, BooleanVariable> globalBooleanVariables;
             
diff --git a/src/storage/prism/RewardModel.cpp b/src/storage/prism/RewardModel.cpp
index 006ee1054..a25d58fc9 100644
--- a/src/storage/prism/RewardModel.cpp
+++ b/src/storage/prism/RewardModel.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace prism {
-        RewardModel::RewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) {
+        RewardModel::RewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) {
             // Nothing to do here.
         }
         
diff --git a/src/storage/prism/RewardModel.h b/src/storage/prism/RewardModel.h
index 6c172c744..9e9498843 100644
--- a/src/storage/prism/RewardModel.h
+++ b/src/storage/prism/RewardModel.h
@@ -9,7 +9,7 @@
 
 namespace storm {
     namespace prism {
-        class RewardModel {
+        class RewardModel : public LocatedInformation {
         public:
             /*!
              * Creates a reward model with the given name, state and transition rewards.
@@ -17,15 +17,17 @@ namespace storm {
              * @param rewardModelName The name of the reward model.
              * @param stateRewards A vector of state-based rewards.
              * @param transitionRewards A vector of transition-based rewards.
+             * @param filename The filename in which the reward model is defined.
+             * @param lineNumber The line number in which the reward model is defined.
              */
-            RewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards);
+            RewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             RewardModel() = default;
-            RewardModel(RewardModel const& otherVariable) = default;
-            RewardModel& operator=(RewardModel const& otherVariable)= default;
-            RewardModel(RewardModel&& otherVariable) = default;
-            RewardModel& operator=(RewardModel&& otherVariable) = default;
+            RewardModel(RewardModel const& other) = default;
+            RewardModel& operator=(RewardModel const& other)= default;
+            RewardModel(RewardModel&& other) = default;
+            RewardModel& operator=(RewardModel&& other) = default;
             
             /*!
              * Retrieves the name of the reward model.
diff --git a/src/storage/prism/StateReward.cpp b/src/storage/prism/StateReward.cpp
index c4bcbd428..7e36406c5 100644
--- a/src/storage/prism/StateReward.cpp
+++ b/src/storage/prism/StateReward.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace prism {
-        StateReward::StateReward(storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression) : statePredicateExpression(statePredicateExpression), rewardValueExpression(rewardValueExpression) {
+        StateReward::StateReward(storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), statePredicateExpression(statePredicateExpression), rewardValueExpression(rewardValueExpression) {
             // Nothing to do here.
         }
         
diff --git a/src/storage/prism/StateReward.h b/src/storage/prism/StateReward.h
index bdd08d446..5eb98886f 100644
--- a/src/storage/prism/StateReward.h
+++ b/src/storage/prism/StateReward.h
@@ -1,11 +1,12 @@
 #ifndef STORM_STORAGE_PRISM_STATEREWARD_H_
 #define STORM_STORAGE_PRISM_STATEREWARD_H_
 
+#include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace prism {
-        class StateReward {
+        class StateReward : public LocatedInformation {
         public:
             /*!
              * Creates a state reward for the states satisfying the given expression with the value given by a second
@@ -13,15 +14,17 @@ namespace storm {
              *
              * @param statePredicateExpression The predicate that states earning this state-based reward need to satisfy.
              * @param rewardValueExpression An expression specifying the values of the rewards to attach to the states.
+             * @param filename The filename in which the state reward is defined.
+             * @param lineNumber The line number in which the state reward is defined.
              */
-            StateReward(storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression);
+            StateReward(storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             StateReward() = default;
-            StateReward(StateReward const& otherVariable) = default;
-            StateReward& operator=(StateReward const& otherVariable)= default;
-            StateReward(StateReward&& otherVariable) = default;
-            StateReward& operator=(StateReward&& otherVariable) = default;
+            StateReward(StateReward const& other) = default;
+            StateReward& operator=(StateReward const& other)= default;
+            StateReward(StateReward&& other) = default;
+            StateReward& operator=(StateReward&& other) = default;
             
             /*!
              * Retrieves the state predicate that is associated with this state reward.
diff --git a/src/storage/prism/TransitionReward.cpp b/src/storage/prism/TransitionReward.cpp
index f972f1270..a5b81e55f 100644
--- a/src/storage/prism/TransitionReward.cpp
+++ b/src/storage/prism/TransitionReward.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace prism {
-        TransitionReward::TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression) : commandName(commandName), statePredicateExpression(statePredicateExpression), rewardValueExpression(rewardValueExpression) {
+        TransitionReward::TransitionReward(std::string const& commandName, storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), commandName(commandName), statePredicateExpression(statePredicateExpression), rewardValueExpression(rewardValueExpression) {
             // Nothing to do here.
         }
         
diff --git a/src/storage/prism/TransitionReward.h b/src/storage/prism/TransitionReward.h
index 1fb783101..1232e5b51 100644
--- a/src/storage/prism/TransitionReward.h
+++ b/src/storage/prism/TransitionReward.h
@@ -1,11 +1,12 @@
 #ifndef STORM_STORAGE_PRISM_TRANSITIONREWARD_H_
 #define STORM_STORAGE_PRISM_TRANSITIONREWARD_H_
 
+#include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace prism {
-        class TransitionReward {
+        class TransitionReward : public LocatedInformation {
         public:
             /*!
              * Creates a transition reward for the transitions with the given name emanating from states satisfying the
@@ -15,15 +16,17 @@ namespace storm {
              * @param statePredicateExpression The predicate that needs to hold before taking a transition with the previously
              * specified name in order to obtain the reward.
              * @param rewardValueExpression An expression specifying the values of the rewards to attach to the transitions.
+             * @param filename The filename in which the transition reward is defined.
+             * @param lineNumber The line number in which the transition reward is defined.
              */
-            TransitionReward(std::string const& actionName, storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression);
+            TransitionReward(std::string const& actionName, storm::expressions::Expression const& statePredicateExpression, storm::expressions::Expression const& rewardValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             TransitionReward() = default;
-            TransitionReward(TransitionReward const& otherVariable) = default;
-            TransitionReward& operator=(TransitionReward const& otherVariable)= default;
-            TransitionReward(TransitionReward&& otherVariable) = default;
-            TransitionReward& operator=(TransitionReward&& otherVariable) = default;
+            TransitionReward(TransitionReward const& other) = default;
+            TransitionReward& operator=(TransitionReward const& other)= default;
+            TransitionReward(TransitionReward&& other) = default;
+            TransitionReward& operator=(TransitionReward&& other) = default;
             
             /*!
              * Retrieves the action name that is associated with this transition reward.
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index f08627479..da92823bb 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -3,25 +3,25 @@
 
 namespace storm {
     namespace prism {
-        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments) : likelihoodExpression(likelihoodExpression), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments), globalIndex(globalIndex) {
+        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(likelihoodExpression), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments), globalIndex(globalIndex) {
             // Nothing to do here.
         }
         
-        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming) : likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), booleanAssignments(), integerAssignments(), globalIndex(newGlobalIndex) {
+        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), booleanAssignments(), integerAssignments(), globalIndex(newGlobalIndex) {
             for (auto const& variableAssignmentPair : update.getBooleanAssignments()) {
                 auto const& namePair = renaming.find(variableAssignmentPair.first);
                 if (namePair != renaming.end()) {
-                    this->booleanAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming));
+                    this->booleanAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
                 } else {
-                    this->booleanAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming));
+                    this->booleanAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
                 }
             }
             for (auto const& variableAssignmentPair : update.getIntegerAssignments()) {
                 auto const& namePair = renaming.find(variableAssignmentPair.first);
                 if (renaming.count(variableAssignmentPair.first) > 0) {
-                    this->integerAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming));
+                    this->integerAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
                 } else {
-                    this->integerAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming));
+                    this->integerAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
                 }
             }
             this->likelihoodExpression = update.getLikelihoodExpression().substitute<std::map>(renaming);
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index 878e394c3..4999c04bd 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -3,11 +3,12 @@
 
 #include <map>
 
-#include "Assignment.h"
+#include "src/storage/prism/LocatedInformation.h"
+#include "src/storage/prism/Assignment.h"
 
 namespace storm {
     namespace prism {
-        class Update {
+        class Update : public LocatedInformation {
         public:
             /*!
              * Creates an update with the given expression specifying the likelihood and the mapping of variable to
@@ -16,8 +17,10 @@ namespace storm {
              * @param globalIndex The global index of the update.
              * @param likelihoodExpression An expression specifying the likelihood of this update.
              * @param assignments A map of variable names to their assignments.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            Update(uint_fast64_t index, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments);
+            Update(uint_fast64_t index, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given update and performs the provided renaming.
@@ -25,15 +28,17 @@ namespace storm {
              * @param update The update that is to be copied.
              * @param newGlobalIndex The global index of the resulting update.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming);
+            Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Update() = default;
-            Update(Update const& otherVariable) = default;
-            Update& operator=(Update const& otherVariable)= default;
-            Update(Update&& otherVariable) = default;
-            Update& operator=(Update&& otherVariable) = default;
+            Update(Update const& other) = default;
+            Update& operator=(Update const& other)= default;
+            Update(Update&& other) = default;
+            Update& operator=(Update&& other) = default;
             
             /*!
              * Retrieves the expression for the likelihood of this update.
diff --git a/src/storage/prism/Variable.cpp b/src/storage/prism/Variable.cpp
index a6f6f57ae..8ec4f2a98 100644
--- a/src/storage/prism/Variable.cpp
+++ b/src/storage/prism/Variable.cpp
@@ -4,11 +4,11 @@
 
 namespace storm {
     namespace prism {
-        Variable::Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue) : variableName(variableName), initialValueExpression(initialValueExpression), defaultInitialValue(defaultInitialValue) {
+        Variable::Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(variableName), initialValueExpression(initialValueExpression), defaultInitialValue(defaultInitialValue) {
             // Nothing to do here.
         }
         
-        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming) : variableName(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
+        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
             // Intentionally left empty.
         }
         
diff --git a/src/storage/prism/Variable.h b/src/storage/prism/Variable.h
index ef77a2c2d..51516bc24 100644
--- a/src/storage/prism/Variable.h
+++ b/src/storage/prism/Variable.h
@@ -3,11 +3,12 @@
 
 #include <map>
 
+#include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace prism {
-        class Variable {
+        class Variable : public LocatedInformation {
         public:
             // Create default implementations of constructors/assignment.
             Variable(Variable const& otherVariable) = default;
@@ -47,8 +48,10 @@ namespace storm {
              * @param initialValueExpression The constant expression that defines the initial value of the variable.
              * @param hasDefaultInitialValue A flag indicating whether the initial value of the variable is its default
              * value.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue);
+            Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given variable and performs the provided renaming.
@@ -56,8 +59,10 @@ namespace storm {
              * @param oldVariable The variable to copy.
              * @param newName New name of this variable.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
+             * @param filename The filename in which the variable is defined.
+             * @param lineNumber The line number in which the variable is defined.
              */
-            Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming);
+            Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
         private:
             // The name of the variable.

From eb2b2fed305072c73f031db7034a7292951450d0 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 8 Apr 2014 17:19:41 +0200
Subject: [PATCH 065/147] Hotfix for DD abstraction layer: copy and paste
 mistake in operator !\= is now fixed.

Former-commit-id: b815b7d7e8a1ac47e4f107fb690278722c96f690
---
 src/storage/dd/CuddDd.cpp              | 2 +-
 test/functional/storage/CuddDdTest.cpp | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 69fadf5c9..0e163c5f7 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -16,7 +16,7 @@ namespace storm {
         }
         
         bool Dd<DdType::CUDD>::operator!=(Dd<DdType::CUDD> const& other) const {
-            return this->cuddAdd == other.getCuddAdd();
+            return this->cuddAdd != other.getCuddAdd();
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::operator+(Dd<DdType::CUDD> const& other) const {
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 9230f00e3..8a5be849a 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -118,6 +118,9 @@ TEST(CuddDd, OperatorTest) {
     manager->addMetaVariable("x", 1, 9);
     EXPECT_TRUE(manager->getZero() == manager->getZero());
     EXPECT_FALSE(manager->getZero() == manager->getOne());
+
+    EXPECT_FALSE(manager->getZero() != manager->getZero());
+    EXPECT_TRUE(manager->getZero() != manager->getOne());
     
     storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne();
     storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getOne();

From 7610bc8e76d5927f02693d2bb01dca0fa216733d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 8 Apr 2014 20:52:15 +0200
Subject: [PATCH 066/147] Started reducing the complexity in the PRISM grammar.

Former-commit-id: c17dc6d27bf1ca822cbe7510825b2f5aa9c9e1a8
---
 src/parser/prismparser/PrismGrammar.cpp   | 285 +++++++---------------
 src/parser/prismparser/PrismGrammar.h     | 207 +++++-----------
 src/parser/prismparser/Tokens.h           |  79 ++++--
 src/storage/expressions/Expression.h      |   2 +-
 src/storage/expressions/Expressions.h     |  13 +
 src/storage/prism/Program.cpp             |   8 +-
 src/storage/prism/Program.h               |  17 +-
 src/storage/prism/Update.cpp              |  63 ++---
 src/storage/prism/Update.h                |  48 +---
 test/functional/parser/ParsePrismTest.cpp |  32 ---
 10 files changed, 269 insertions(+), 485 deletions(-)
 create mode 100644 src/storage/expressions/Expressions.h
 delete mode 100644 test/functional/parser/ParsePrismTest.cpp

diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp
index b6de4f0f4..7c81b31ce 100644
--- a/src/parser/prismparser/PrismGrammar.cpp
+++ b/src/parser/prismparser/PrismGrammar.cpp
@@ -1,152 +1,96 @@
-/*
- * PrismGrammar.cpp
- *
- *  Created on: 11.01.2013
- *      Author: chris
- */
-
-// Needed for file IO.
-#include <fstream>
-#include <iomanip>
-#include <limits>
-
-#include "PrismGrammar.h"
-
-#include "src/utility/OsDetection.h"
-
-#include "src/parser/prismparser/Includes.h"
-#include "src/parser/prismparser/BooleanExpressionGrammar.h"
-#include "src/parser/prismparser/ConstBooleanExpressionGrammar.h"
-#include "src/parser/prismparser/ConstDoubleExpressionGrammar.h"
-#include "src/parser/prismparser/ConstIntegerExpressionGrammar.h"
-#include "src/parser/prismparser/IntegerExpressionGrammar.h"
-#include "src/parser/prismparser/IdentifierGrammars.h"
-#include "src/parser/prismparser/VariableState.h"
+#include "src/parser/prismparser/PrismGrammar.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
-// Some typedefs and namespace definitions to reduce code size.
-typedef std::string::const_iterator BaseIteratorType;
-typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
-namespace qi = boost::spirit::qi;
-namespace phoenix = boost::phoenix;
-
 namespace storm {
     namespace parser {
         namespace prism {
-            
-            void PrismGrammar::addLabel(std::string const& name, std::shared_ptr<BaseExpression> const& value, std::map<std::string, std::unique_ptr<BaseExpression>>& nameToExpressionMap) {
-                this->state->labelNames_.add(name, name);
-                nameToExpressionMap[name] = value->clone();
-            }
-            
-            void PrismGrammar::addIntegerAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& value, std::map<std::string, Assignment>& variableToAssignmentMap) {
-                this->state->assignedIntegerVariables_.add(variable, variable);
-                variableToAssignmentMap[variable] = Assignment(variable, value->clone());
-            }
-            
-            void PrismGrammar::addBooleanAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& value, std::map<std::string, Assignment>& variableToAssigmentMap) {
-                this->state->assignedBooleanVariables_.add(variable, variable);
-                variableToAssigmentMap[variable] = Assignment(variable, value->clone());
-            }
-            
-            void PrismGrammar::addUndefinedBooleanConstant(std::string const& name, std::map<std::string, std::unique_ptr<BooleanConstantExpression>>& nameToExpressionMap) {
-                this->state->booleanConstants_.add(name, std::shared_ptr<BaseExpression>(new BooleanConstantExpression(name)));
-                this->state->allConstantNames_.add(name, name);
-                nameToExpressionMap.emplace(name, std::unique_ptr<BooleanConstantExpression>(new BooleanConstantExpression(dynamic_cast<BooleanConstantExpression&>(*this->state->booleanConstants_.at(name)))));
-            }
-            
-            void PrismGrammar::addUndefinedIntegerConstant(std::string const& name, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>& nameToExpressionMap) {
-                this->state->integerConstants_.add(name, std::shared_ptr<BaseExpression>(new IntegerConstantExpression(name)));
-                this->state->allConstantNames_.add(name, name);
-                nameToExpressionMap.emplace(name, std::unique_ptr<IntegerConstantExpression>(new IntegerConstantExpression(dynamic_cast<IntegerConstantExpression&>(*this->state->integerConstants_.at(name)))));
-            }
-            
-            void PrismGrammar::addUndefinedDoubleConstant(std::string const& name, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>& nameToExpressionMap) {
-                this->state->doubleConstants_.add(name, std::shared_ptr<BaseExpression>(new DoubleConstantExpression(name)));
-                this->state->allConstantNames_.add(name, name);
-                nameToExpressionMap.emplace(name, std::unique_ptr<DoubleConstantExpression>(new DoubleConstantExpression(dynamic_cast<DoubleConstantExpression&>(*this->state->doubleConstants_.at(name)))));
-            }
-            
-            Module PrismGrammar::renameModule(std::string const& newName, std::string const& oldName, std::map<std::string, std::string> const& renaming) {
-                this->state->moduleNames_.add(newName, newName);
-                Module* old = this->moduleMap_.find(oldName);
-                if (old == nullptr) {
-                    LOG4CPLUS_ERROR(logger, "Renaming module failed: module " << oldName << " does not exist.");
-                    throw storm::exceptions::InvalidArgumentException() << "Renaming module failed: module " << oldName << " does not exist.";
-                }
-                Module res(*old, newName, renaming, *this->state);
-                this->moduleMap_.at(newName) = res;
-                return res;
-            }
-            
-            Module PrismGrammar::createModule(std::string const& name, std::vector<BooleanVariable> const& bools, std::vector<IntegerVariable> const& ints, std::map<std::string, uint_fast64_t> const& boolids, std::map<std::string, uint_fast64_t> const& intids, std::vector<storm::ir::Command> const& commands) {
-                this->state->moduleNames_.add(name, name);
-                Module res(name, bools, ints, boolids, intids, commands);
-                this->moduleMap_.at(name) = res;
-                return res;
-            }
-            
-            void PrismGrammar::createIntegerVariable(std::string const& name, std::shared_ptr<BaseExpression> const& lower, std::shared_ptr<BaseExpression> const& upper, std::shared_ptr<BaseExpression> const& init, std::vector<IntegerVariable>& vars, std::map<std::string, uint_fast64_t>& varids, bool isGlobalVariable) {
-                uint_fast64_t id = this->state->addIntegerVariable(name);
-                uint_fast64_t newLocalIndex = this->state->nextLocalIntegerVariableIndex;
-                vars.emplace_back(newLocalIndex, id, name, lower != nullptr ? lower->clone() : nullptr, upper != nullptr ? upper->clone() : nullptr, init != nullptr ? init->clone() : nullptr);
-                varids[name] = newLocalIndex;
-                ++this->state->nextLocalIntegerVariableIndex;
-                this->state->localIntegerVariables_.add(name, name);
-                if (isGlobalVariable) {
-                    this->state->globalIntegerVariables_.add(name, name);
-                }
-            }
-            
-            void PrismGrammar::createBooleanVariable(std::string const& name, std::shared_ptr<BaseExpression> const& init, std::vector<BooleanVariable>& vars, std::map<std::string, uint_fast64_t>& varids, bool isGlobalVariable) {
-                uint_fast64_t id = this->state->addBooleanVariable(name);
-                uint_fast64_t newLocalIndex = this->state->nextLocalBooleanVariableIndex;
-                vars.emplace_back(newLocalIndex, id, name, init != nullptr ? init->clone() : nullptr);
-                varids[name] = newLocalIndex;
-                ++this->state->nextLocalBooleanVariableIndex;
-                this->state->localBooleanVariables_.add(name, name);
-                if (isGlobalVariable) {
-                    this->state->globalBooleanVariables_.add(name, name);
-                }
-            }
-            
-            StateReward createStateReward(std::shared_ptr<BaseExpression> const& guard, std::shared_ptr<BaseExpression> const& reward) {
-                return StateReward(guard->clone(), reward->clone());
-            }
-            TransitionReward createTransitionReward(std::string const& label, std::shared_ptr<BaseExpression> const& guard, std::shared_ptr<BaseExpression> const& reward) {
-                return TransitionReward(label, guard->clone(), reward->clone());
-            }
-            void createRewardModel(std::string const& name, std::vector<StateReward>& stateRewards, std::vector<TransitionReward>& transitionRewards, std::map<std::string, RewardModel>& mapping) {
-                mapping[name] = RewardModel(name, stateRewards, transitionRewards);
-            }
-            Update PrismGrammar::createUpdate(std::shared_ptr<BaseExpression> const& likelihood, std::map<std::string, Assignment> const& bools, std::map<std::string, Assignment> const& ints) {
-                this->state->nextGlobalUpdateIndex++;
-                return Update(this->state->getNextGlobalUpdateIndex() - 1, likelihood != nullptr ? likelihood->clone() : nullptr, bools, ints);
-            }
-            Command PrismGrammar::createCommand(std::string const& label, std::shared_ptr<BaseExpression> const& guard, std::vector<Update> const& updates) {
-                this->state->nextGlobalCommandIndex++;
-                return Command(this->state->getNextGlobalCommandIndex() - 1, label, guard->clone(), updates);
-            }
-            Program createProgram(
-                                  Program::ModelType modelType,
-                                  std::map<std::string, std::unique_ptr<BooleanConstantExpression>> const& undefBoolConst,
-                                  std::map<std::string, std::unique_ptr<IntegerConstantExpression>> const& undefIntConst,
-                                  std::map<std::string, std::unique_ptr<DoubleConstantExpression>> const& undefDoubleConst,
-                                  GlobalVariableInformation const& globalVariableInformation,
-                                  std::vector<Module> const& modules,
-                                  std::map<std::string, RewardModel> const& rewards,
-                                  std::map<std::string, std::unique_ptr<BaseExpression>> const& labels) {
-                return Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst,
-                               globalVariableInformation.booleanVariables, globalVariableInformation.integerVariables,
-                               globalVariableInformation.booleanVariableToIndexMap,
-                               globalVariableInformation.integerVariableToIndexMap, modules, rewards, labels);
-            }
-            
-            PrismGrammar::PrismGrammar() : PrismGrammar::base_type(start), state(new VariableState()) {
+            PrismGrammar::PrismGrammar() : PrismGrammar::base_type(start) {
+                // Parse simple identifier.
+                identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]] - keywords_;
+                identifier.name("identifier");
+                
+                // Parse a composed expression.
+                expression %= (booleanExpression | numericalExpression);
+                expression.name("expression");
+                
+                booleanExpression %= orExpression;
+                expression.name("boolean expression");
+                
+                orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = qi::_val * qi::_1];
+                orExpression.name("boolean expression");
+                
+                andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = qi::_val * qi::_1];
+                andExpression.name("boolean expression");
+                
+                notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = !qi::_1];
+                notExpression.name("boolean expression");
+                
+                atomicBooleanExpression %= relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")");
+                atomicBooleanExpression.name("boolean expression");
+                
+                relativeExpression = ((numericalExpression >> ">") > numericalExpression)[qi::_val = qi::_1 > qi::_2] | ((numericalExpression >> ">=") > numericalExpression)[qi::_val = qi::_1 >= qi::_2] | ((numericalExpression >> "<") > numericalExpression)[qi::_val = qi::_1 < qi::_2] | ((numericalExpression >> "<=") > numericalExpression)[qi::_val = qi::_1 <= qi::_2];
+                relativeExpression.name("relative expression");
+                
+                booleanVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createBooleanVariable, qi::_1)];
+                booleanVariableExpression.name("boolean variable");
+                
+                numericalExpression %= plusExpression;
+                numericalExpression.name("numerical expression");
+                
+                plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = qi::_val + qi::_1] .else_ [qi::_val = qi::_val - qi::_1]];
+                plusExpression.name("numerical expression");
+                
+                multiplicationExpression = atomicNumericalExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicNumericalExpression[qi::_val = qi::_val * qi::_1]);
+                multiplicationExpression.name("numerical expression");
+                
+                atomicNumericalExpression %= minMaxExpression | floorCeilExpression | numericalVariableExpression | qi::lit("(") >> numericalExpression >> qi::lit(")");
+                atomicNumericalExpression.name("numerical expression");
+                
+                minMaxExpression %= ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(",") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]];
+                minMaxExpression.name("min/max expression");
+                
+                floorCeilExpression %= ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]];
+                floorCeilExpression.name("integer floor/ceil expression");
+
+                numericalVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleVariable, qi::_1)];
+                numericalVariableExpression.name("numerical variable");
+                
+                // Parse a model type.
+                modelTypeDefinition = modelType_;
+                modelTypeDefinition.name("model type");
+                
+                // This block defines all entities that are needed for parsing constant definitions.
+                definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=") > expression > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+                definedBooleanConstantDefinition.name("defined boolean constant declaration");
+                
+                definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+                definedIntegerConstantDefinition.name("defined integer constant declaration");
+                definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+                definedDoubleConstantDefinition.name("defined double constant declaration");
+                undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, this, qi::_1, qi::_r1)];
+                undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
+                undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, this, qi::_1, qi::_r1)];
+                undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
+                undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, this, qi::_1, qi::_r1)];
+                undefinedDoubleConstantDefinition.name("undefined double constant definition");
+                definedConstantDefinition %= (definedBooleanConstantDefinition(qi::_r1) | definedIntegerConstantDefinition(qi::_r2) | definedDoubleConstantDefinition(qi::_r3));
+                definedConstantDefinition.name("defined constant definition");
+                undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3));
+                undefinedConstantDefinition.name("undefined constant definition");
+                constantDefinitionList = *(undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3) | definedConstantDefinition(qi::_r4, qi::_r5, qi::_r6));
+                constantDefinitionList.name("constant definition list");
+                
+                // Parse the ingredients of a probabilistic program.
+                start = (qi::eps >
+                         modelTypeDefinition >
+                         constantDefinitionList(qi::_a, qi::_b, qi::_c, qi::_d, qi::_e, qi::_f) >
+                         formulaDefinitionList >
+                         globalVariableDefinitionList(qi::_d) >
+                         moduleDefinitionList >
+                         rewardDefinitionList(qi::_e) >
+                         labelDefinitionList(qi::_f))[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2, qi::_e, qi::_f)];
+                start.name("probabilistic program declaration");
+
                 
                 labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> FreeIdentifierGrammar::instance(this->state) >> -qi::lit("\"") >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))
                 [phoenix::bind(&PrismGrammar::addLabel, this, qi::_1, qi::_2, qi::_r1)];
@@ -222,26 +166,6 @@ namespace storm {
                 globalVariableDefinitionList = *(qi::lit("global") > (booleanVariableDefinition(bind(&GlobalVariableInformation::booleanVariables, qi::_r1), bind(&GlobalVariableInformation::booleanVariableToIndexMap, qi::_r1), true) | integerVariableDefinition(bind(&GlobalVariableInformation::integerVariables, qi::_r1), bind(&GlobalVariableInformation::integerVariableToIndexMap, qi::_r1), true)));
                 globalVariableDefinitionList.name("global variable declaration list");
                 
-                // This block defines all entities that are needed for parsing constant definitions.
-                definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
-                definedBooleanConstantDefinition.name("defined boolean constant declaration");
-                definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
-                definedIntegerConstantDefinition.name("defined integer constant declaration");
-                definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
-                definedDoubleConstantDefinition.name("defined double constant declaration");
-                undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, this, qi::_1, qi::_r1)];
-                undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
-                undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, this, qi::_1, qi::_r1)]; 
-                undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
-                undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, this, qi::_1, qi::_r1)];
-                undefinedDoubleConstantDefinition.name("undefined double constant declaration");
-                definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
-                definedConstantDefinition.name("defined constant declaration");
-                undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3));
-                undefinedConstantDefinition.name("undefined constant declaration");
-                constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3));
-                constantDefinitionList.name("constant declaration list");
-                
                 constantBooleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstBooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantBooleanFormulas_.add, qi::_1, qi::_2)];
                 constantBooleanFormulaDefinition.name("constant boolean formula definition");
                 booleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->booleanFormulas_.add, qi::_1, qi::_2)];
@@ -256,40 +180,7 @@ namespace storm {
                 formulaDefinition.name("formula definition");
                 formulaDefinitionList = *formulaDefinition;
                 formulaDefinitionList.name("formula definition list");
-
-                // This block defines all entities that are needed for parsing a program.
-                modelTypeDefinition = modelType_;
-                modelTypeDefinition.name("model type");
-                start = (qi::eps >
-                         modelTypeDefinition >
-                         constantDefinitionList(qi::_a, qi::_b, qi::_c) >
-                         formulaDefinitionList >
-                         globalVariableDefinitionList(qi::_d) >
-                         moduleDefinitionList >
-                         rewardDefinitionList(qi::_e) >
-                         labelDefinitionList(qi::_f))[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2, qi::_e, qi::_f)];
-                start.name("probabilistic program declaration");
-            }
-            
-            void PrismGrammar::prepareForSecondRun() {
-                LOG4CPLUS_INFO(logger, "Preparing parser for second run.");
-                this->state->prepareForSecondRun();
-                BooleanExpressionGrammar::secondRun();
-                ConstBooleanExpressionGrammar::secondRun();
-                ConstDoubleExpressionGrammar::secondRun();
-                ConstIntegerExpressionGrammar::secondRun();
-                IntegerExpressionGrammar::secondRun();
-            }
-            
-            void PrismGrammar::resetGrammars() {
-                LOG4CPLUS_INFO(logger, "Resetting grammars.");
-                BooleanExpressionGrammar::resetInstance();
-                ConstBooleanExpressionGrammar::resetInstance();
-                ConstDoubleExpressionGrammar::resetInstance();
-                ConstIntegerExpressionGrammar::resetInstance();
-                IntegerExpressionGrammar::resetInstance();
             }
-            
         } // namespace prism
     } // namespace parser
 } // namespace storm
diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h
index c73420057..77a5406fc 100644
--- a/src/parser/prismparser/PrismGrammar.h
+++ b/src/parser/prismparser/PrismGrammar.h
@@ -34,7 +34,7 @@ using namespace storm::expressions;
 namespace storm {
     namespace parser {
         namespace prism {
-            class PrismGrammar : public qi::grammar<Iterator, Program(), Skipper> {
+            class PrismGrammar : public qi::grammar<Iterator, Program(), qi::locals<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, Module>>, Skipper> {
             public:
                 /*!
                  * Default constructor that creates an empty and functional grammar.
@@ -43,182 +43,89 @@ namespace storm {
                 
             private:
                 // The starting point of the grammar.
-                qi::rule<Iterator, Program(), Skipper> start;
+                // The locals are used for: (a) undefined boolean constants, (b) undefined integer constants, (c) undefined double constants, (d) defined boolean constants, (e) defined integer constants, (f) defined double constants, (g) module name to module map
+                qi::rule<Iterator, Program(), qi::locals<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, Module>>, Skipper> start;
                 
                 // Rules for model type.
                 qi::rule<Iterator, Program::ModelType(), Skipper> modelTypeDefinition;
                 
-                // Rules for global constant definitions.
-                qi::rule<Iterator, qi::unused_type(std::set<std::string>&, std::set<std::string>&, std::set<std::string>&, std::map<std::string, storm::expression::Expression>&, std::map<std::string, storm::expression::Expression>&, std::map<std::string, storm::expression::Expression>&), Skipper> constantDefinitionList;
-                
-                // Rules for global variable definitions
+                // Rules for constant definitions.
+                qi::rule<Iterator, qi::unused_type(std::set<std::string>&, std::set<std::string>&, std::set<std::string>&, std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&), Skipper> constantDefinitionList;
+                qi::rule<Iterator, qi::unused_type(std::set<std::string>&, std::set<std::string>&, std::set<std::string>&), Skipper> undefinedConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&), Skipper> definedConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::set<std::string>&), Skipper> undefinedBooleanConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::set<std::string>&), Skipper> undefinedIntegerConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::set<std::string>&), Skipper> undefinedDoubleConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> definedBooleanConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> definedIntegerConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> definedDoubleConstantDefinition;
+                
+                // Rules for global variable definitions.
                 qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&, std::map<std::string, IntegerVariable>), Skipper> globalVariableDefinitionList;
                 
                 // Rules for modules definition.
                 qi::rule<Iterator, std::vector<Module>(), Skipper> moduleDefinitionList;
-                qi::rule<Iterator, Module(), qi::locals<std::vector<BooleanVariable>, std::vector<IntegerVariable>, std::map<std::string, uint_fast64_t>, std::map<std::string, uint_fast64_t>>, Skipper> moduleDefinition;
-                qi::rule<Iterator, Module(), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
+                qi::rule<Iterator, Module(), qi::locals<std::map<std::string, BooleanVariable>, std::map<std::string, IntegerVariable>>, Skipper> moduleDefinition;
+                qi::rule<Iterator, Module(std::map<std::string, Module>&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
                 
                 // Rules for variable definitions.
-                qi::rule<Iterator, qi::unused_type(std::vector<BooleanVariable>&, std::vector<IntegerVariable>&, std::map<std::string, uint_fast64_t>&, std::map<std::string, uint_fast64_t>&), Skipper> variableDefinition;
-                qi::rule<Iterator, qi::unused_type(std::vector<BooleanVariable>&, std::map<std::string, uint_fast64_t>&, bool), qi::locals<uint_fast64_t, std::shared_ptr<BaseExpression>>, Skipper> booleanVariableDefinition;
-                qi::rule<Iterator, qi::unused_type(std::vector<IntegerVariable>&, std::map<std::string, uint_fast64_t>&, bool), qi::locals<uint_fast64_t, std::shared_ptr<BaseExpression>>, Skipper> integerVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&, std::map<std::string, IntegerVariable>&), Skipper> variableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&), Skipper> booleanVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, IntegerVariable>&), Skipper> integerVariableDefinition;
                 
                 // Rules for command definitions.
                 qi::rule<Iterator, Command(), qi::locals<std::string>, Skipper> commandDefinition;
                 qi::rule<Iterator, std::vector<Update>(), Skipper> updateListDefinition;
-                qi::rule<Iterator, Update(), qi::locals<std::map<std::string, Assignment>, std::map<std::string, Assignment>>, Skipper> updateDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, Assignment>&, std::map<std::string, Assignment>&), Skipper> assignmentDefinitionList;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, Assignment>&, std::map<std::string, Assignment>&), Skipper> assignmentDefinition;
-                
-                // Rules for variable/command names.
-                qi::rule<Iterator, std::string(), Skipper> commandName;
-                qi::rule<Iterator, std::string(), Skipper> unassignedLocalBooleanVariableName;
-                qi::rule<Iterator, std::string(), Skipper> unassignedLocalIntegerVariableName;
+                qi::rule<Iterator, Update(), qi::locals<std::map<std::string, Assignment>>, Skipper> updateDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, Assignment>&), Skipper> assignmentDefinitionList;
+                qi::rule<Iterator, Assignment(), Skipper> assignmentDefinition;
                 
                 // Rules for reward definitions.
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, RewardModel>&), Skipper> rewardDefinitionList;
+                qi::rule<Iterator, std::map<std::string, RewardModel>(), Skipper> rewardDefinitionList;
                 qi::rule<Iterator, qi::unused_type(std::map<std::string, RewardModel>&), qi::locals<std::vector<StateReward>, std::vector<TransitionReward>>, Skipper> rewardDefinition;
                 qi::rule<Iterator, StateReward(), Skipper> stateRewardDefinition;
-                qi::rule<Iterator, TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
+                qi::rule<Iterator, TransitionReward(), Skipper> transitionRewardDefinition;
                 
                 // Rules for label definitions.
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BaseExpression>>&), Skipper> labelDefinitionList;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BaseExpression>>&), Skipper> labelDefinition;
-                
-                // Rules for constant definitions.
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BooleanConstantExpression>>&, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>&, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>&), Skipper> undefinedConstantDefinition;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BooleanConstantExpression>>&), Skipper> undefinedBooleanConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<IntegerConstantExpression>>&), Skipper> undefinedIntegerConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<DoubleConstantExpression>>&), Skipper> undefinedDoubleConstantDefinition;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedBooleanConstantDefinition;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedIntegerConstantDefinition;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedDoubleConstantDefinition;
+                qi::rule<Iterator, std::map<std::string, storm::expressions::Expression>(), Skipper> labelDefinitionList;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> labelDefinition;
                 
                 // Rules for formula definitions.
-                qi::rule<Iterator, qi::unused_type(), Skipper> formulaDefinitionList;
-                qi::rule<Iterator, qi::unused_type(), Skipper> formulaDefinition;
-                qi::rule<Iterator, qi::unused_type(), Skipper> constantIntegerFormulaDefinition;
-                qi::rule<Iterator, qi::unused_type(), Skipper> integerFormulaDefinition;
-                qi::rule<Iterator, qi::unused_type(), Skipper> constantDoubleFormulaDefinition;
-                qi::rule<Iterator, qi::unused_type(), Skipper> constantBooleanFormulaDefinition;
-                qi::rule<Iterator, qi::unused_type(), Skipper> booleanFormulaDefinition;
-
-                // Rules for variable recognition.
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanVariableCreatorExpression;
-                qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<std::shared_ptr<BaseExpression>>, Skipper> integerVariableCreatorExpression;
-                
+                qi::rule<Iterator, std::map<std::string, storm::expressions::Expression>(), Skipper> formulaDefinitionList;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> formulaDefinition;
+                
+                // Rules for identifier parsing.
+                qi::rule<Iterator, std::string(), Skipper> identifier;
+                
+                // Rules for parsing a composed expression.
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> booleanExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> orExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> notExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicBooleanExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> booleanVariableExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> numericalExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> multiplicationExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicNumericalExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> numericalVariableExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
+                
+                // Parsers that recognize special keywords and operations.
                 storm::parser::prism::keywordsStruct keywords_;
                 storm::parser::prism::modelTypeStruct modelType_;
-                storm::parser::prism::relationalOperatorStruct relations_;
-                
-                // A mapping from module names to the modules themselves so they can be looked up for renaming later.
-                struct qi::symbols<char, Module> moduleMap_;
+                storm::parser::prism::BinaryRelationOperatorStruct relationOperator_;
+                storm::parser::prism::BinaryBooleanOperatorStruct binaryBooleanOperator_;
+                storm::parser::prism::UnaryBooleanOperatorStruct unaryBooleanOperator_;
+                storm::parser::prism::BinaryNumericalOperatorStruct binaryNumericalOperator_;
+                storm::parser::prism::UnaryNumericalOperatorStruct unaryNumericalOperator_;
                 
-                /*!
-                 * Adds a label with the given name and expression to the given label-to-expression map.
-                 *
-                 * @param name The name of the label.
-                 * @param expression The expression associated with the label.
-                 * @param nameToExpressionMap The map to which the label is added.
-                 */
-                void addLabel(std::string const& name, std::shared_ptr<BaseExpression> const& value, std::map<std::string, std::unique_ptr<BaseExpression>>& nameToExpressionMap);
-                
-                /*!
-                 * Adds a boolean assignment for the given variable with the given expression and adds it to the
-                 * provided variable-to-assignment map.
-                 *
-                 * @param variable The name of the variable that the assignment targets.
-                 * @param expression The expression that is assigned to the variable.
-                 * @param variableToAssignmentMap The map to which the assignment is added.
-                 */
-                void addBooleanAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& expression, std::map<std::string, Assignment>& variableToAssignmentMap);
-                
-                /*!
-                 * Adds a boolean assignment for the given variable with the given expression and adds it to the
-                 * provided variable-to-assignment map.
-                 *
-                 * @param variable The name of the variable that the assignment targets.
-                 * @param expression The expression that is assigned to the variable.
-                 * @param variableToAssignmentMap The map to which the assignment is added.
-                 */
-                void addIntegerAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& expression, std::map<std::string, Assignment>& variableToAssignmentMap);
-                
-                void addUndefinedBooleanConstant(std::string const& name, std::map<std::string, std::unique_ptr<BooleanConstantExpression>>& nameToExpressionMap);
-
-                void addUndefinedIntegerConstant(std::string const& name, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>& nameToExpressionMap);
-
-                void addUndefinedDoubleConstant(std::string const& name, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>& nameToExpressionMap);
-
-                /*!
-                 * Creates a module by renaming, i.e. takes the module given by the old name, creates a new module
-                 * with the given name which renames all identifiers according to the given mapping.
-                 *
-                 * @param name The name of the new module.
-                 * @param oldName The name of the module that is to be copied (modulo renaming).
-                 * @param renaming A mapping from identifiers to their new names.
-                 */
-                Module renameModule(std::string const& name, std::string const& oldName, std::map<std::string, std::string> const& renaming);
-                
-                /*!
-                 * Creates a new module with the given name, boolean and integer variables and commands.
-                 *
-                 * @param name The name of the module to create.
-                 * @param booleanVariables The boolean variables of the module.
-                 * @param integerVariables The integer variables of the module.
-                 * @param booleanVariableToLocalIndexMap A mapping of boolean variables to module-local indices.
-                 * @param integerVariableToLocalIndexMap A mapping of boolean variables to module-local indices.
-                 * @param commands The commands associated with this module.
-                 */
-                Module createModule(std::string const& name, std::vector<BooleanVariable> const& booleanVariables, std::vector<IntegerVariable> const& integerVariables, std::map<std::string, uint_fast64_t> const& booleanVariableToLocalIndexMap, std::map<std::string, uint_fast64_t> const& integerVariableToLocalIndexMap, std::vector<storm::ir::Command> const& commands);
-                
-                /*!
-                 * Creates an integer variable with the given name, domain and initial value and adds it to the
-                 * provided list of integer variables and the given mappings.
-                 *
-                 * @param name The name of the integer variable.
-                 * @param lower The expression that defines the lower bound of the domain.
-                 * @param upper The expression that defines the upper bound of the domain.
-                 * @param init The expression that defines the initial value of the variable.
-                 * @param integerVariableToGlobalIndexMap A mapping of integer variables to global indices.
-                 * @param isGlobalVariable A flag indicating whether the variable is supposed to be global or not.
-                 */
-                void createIntegerVariable(std::string const& name, std::shared_ptr<BaseExpression> const& lower, std::shared_ptr<BaseExpression> const& upper, std::shared_ptr<BaseExpression> const& init, std::vector<IntegerVariable>& integerVariables, std::map<std::string, uint_fast64_t>& integerVariableToGlobalIndexMap, bool isGlobalVariable);
-                
-                /*!
-                 * Creates an boolean variable with the given name and initial value and adds it to the
-                 * provided list of boolean variables and the given mappings.
-                 *
-                 * @param name The name of the boolean variable.
-                 * @param init The expression that defines the initial value of the variable.
-                 * @param booleanVariableToGlobalIndexMap A mapping of boolean variables to global indices.
-                 * @param isGlobalVariable A flag indicating whether the variable is supposed to be global or not.
-                 */
-                void createBooleanVariable(std::string const& name, std::shared_ptr<BaseExpression> const& init, std::vector<BooleanVariable>& booleanVariables, std::map<std::string, uint_fast64_t>& booleanVariableToGlobalIndexMap, bool isGlobalVariable);
-                
-                /*!
-                 * Creates a command with the given label, guard and updates.
-                 *
-                 * @param label The label of the command.
-                 * @param guard The guard of the command.
-                 * @param updates The updates associated with the command.
-                 */
-                Command createCommand(std::string const& label, std::shared_ptr<BaseExpression> const& guard, std::vector<Update> const& updates);
-                
-                /*!
-                 * Creates an update with the given likelihood and the given assignments to boolean and integer variables, respectively.
-                 *
-                 * @param likelihood The likelihood of this update being executed.
-                 * @param booleanAssignments The assignments to boolean variables this update involves.
-                 * @param integerAssignments The assignments to integer variables this update involves.
-                 */
-                Update createUpdate(std::shared_ptr<BaseExpression> const& likelihood, std::map<std::string, Assignment> const& booleanAssignments, std::map<std::string, Assignment> const& integerAssignments);
+                // Helper methods that add data to data structures.
                 
             };
-            
-            
         } // namespace prism
     } // namespace parser
 } // namespace storm
diff --git a/src/parser/prismparser/Tokens.h b/src/parser/prismparser/Tokens.h
index bcaefce7b..866bbbf24 100644
--- a/src/parser/prismparser/Tokens.h
+++ b/src/parser/prismparser/Tokens.h
@@ -1,7 +1,8 @@
 #ifndef STORM_PARSER_PRISMPARSER_TOKENS_H_
 #define	STORM_PARSER_PRISMPARSER_TOKENS_H_
 
-#include "src/storage/expressions/Expression.h"
+#include "src/storage/prism/Program.h"
+#include "src/storage/expressions/Expressions.h"
 
 namespace storm {
     namespace parser {
@@ -10,14 +11,14 @@ namespace storm {
              * A structure mapping the textual representation of a model type to the model type
              * representation of the intermediate representation.
              */
-            struct modelTypeStruct : qi::symbols<char, Program::ModelType> {
+            struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
                 modelTypeStruct() {
                     add
-                    ("dtmc", Program::ModelType::DTMC)
-                    ("ctmc", Program::ModelType::CTMC)
-                    ("mdp", Program::ModelType::MDP)
-                    ("ctmdp", Program::ModelType::CTMDP)
-                    ("ma", Program::ModelType::MA);
+                    ("dtmc", storm::prism::Program::ModelType::DTMC)
+                    ("ctmc", storm::prism::Program::ModelType::CTMC)
+                    ("mdp", storm::prism::Program::ModelType::MDP)
+                    ("ctmdp", storm::prism::Program::ModelType::CTMDP)
+                    ("ma", storm::prism::Program::ModelType::MA);
                 }
             };
             
@@ -45,17 +46,63 @@ namespace storm {
             };
             
             /*!
-             * A structure mapping the textual representation of a binary relation.
+             * A structure mapping the textual representation of binary relations to the corresponding enum values.
              */
-            struct relationalOperatorStruct : qi::symbols<char, BinaryRelationExpression::RelationType> {
-                relationalOperatorStruct() {
+            struct BinaryRelationOperatorStruct : qi::symbols<char, storm::expressions::BinaryRelationExpression::RelationType> {
+                BinaryRelationOperatorStruct() {
                     add
-                    ("=", BinaryRelationExpression::RelationType::EQUAL)
-                    ("!=", BinaryRelationExpression::RelationType::NOT_EQUAL)
-                    ("<", BinaryRelationExpression::RelationType::LESS)
-                    ("<=", BinaryRelationExpression::RelationType::LESS_OR_EQUAL)
-                    (">", BinaryRelationExpression::RelationType::GREATER)
-                    (">=", BinaryRelationExpression::RelationType::GREATER_OR_EQUAL);
+                    ("=", storm::expressions::BinaryRelationExpression::RelationType::Equal)
+                    ("!=", storm::expressions::BinaryRelationExpression::RelationType::NotEqual)
+                    ("<", storm::expressions::BinaryRelationExpression::RelationType::Less)
+                    ("<=", storm::expressions::BinaryRelationExpression::RelationType::LessOrEqual)
+                    (">", storm::expressions::BinaryRelationExpression::RelationType::Greater)
+                    (">=", storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual);
+                }
+            };
+            
+            /*!
+             * A structure mapping the textual representation of binary operators to the corresponding enum values.
+             */
+            struct BinaryBooleanOperatorStruct : qi::symbols<char, storm::expressions::BinaryBooleanFunctionExpression::OperatorType> {
+                BinaryBooleanOperatorStruct() {
+                    add
+                    ("&", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And)
+                    ("|", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or)
+                    ("=>", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Implies)
+                    ("<=>", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff);
+                }
+            };
+
+            /*!
+             * A structure mapping the textual representation of binary operators to the corresponding enum values.
+             */
+            struct UnaryBooleanOperatorStruct : qi::symbols<char, storm::expressions::UnaryBooleanFunctionExpression::OperatorType> {
+                UnaryBooleanOperatorStruct() {
+                    add
+                    ("!", storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not);
+                }
+            };
+            
+            /*!
+             * A structure mapping the textual representation of binary boolean operators to the corresponding enum values.
+             */
+            struct BinaryNumericalOperatorStruct : qi::symbols<char, storm::expressions::BinaryNumericalFunctionExpression::OperatorType> {
+                BinaryNumericalOperatorStruct() {
+                    add
+                    ("+", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus)
+                    ("-", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Minus)
+                    ("*", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times)
+                    ("/", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide);
+                }
+            };
+            
+            /*!
+             * A structure mapping the textual representation of binary operators to the corresponding enum values.
+             */
+            struct UnaryNumericalOperatorStruct : qi::symbols<char, storm::expressions::UnaryNumericalFunctionExpression::OperatorType> {
+                UnaryNumericalOperatorStruct() {
+                    add
+                    ("!", storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus);
                 }
             };
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 875bcfbdc..e7768432d 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -1,7 +1,7 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 
-#include <functional>
+#include <memory>
 
 #include "src/storage/expressions/BaseExpression.h"
 
diff --git a/src/storage/expressions/Expressions.h b/src/storage/expressions/Expressions.h
new file mode 100644
index 000000000..09febb4a4
--- /dev/null
+++ b/src/storage/expressions/Expressions.h
@@ -0,0 +1,13 @@
+#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/BinaryRelationExpression.h"
+#include "src/storage/expressions/BooleanConstantExpression.h"
+#include "src/storage/expressions/BooleanLiteralExpression.h"
+#include "src/storage/expressions/DoubleConstantExpression.h"
+#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/IntegerConstantExpression.h"
+#include "src/storage/expressions/IntegerLiteralExpression.h"
+#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
+#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/VariableExpression.h"
+#include "src/storage/expressions/Expression.h"
\ No newline at end of file
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index c01e24c0d..97daf8142 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace prism {
-        Program::Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), undefinedBooleanConstants(undefinedBooleanConstants), definedBooleanConstants(definedBooleanConstants), undefinedIntegerConstants(undefinedIntegerConstants), definedIntegerConstants(definedIntegerConstants), undefinedDoubleConstants(undefinedDoubleConstants), definedDoubleConstants(definedDoubleConstants), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables), modules(modules), rewardModels(rewardModels), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+        Program::Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> const& definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> const& definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> const& definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::map<std::string, storm::expressions::Expression>const& formulas, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), undefinedBooleanConstants(undefinedBooleanConstants), definedBooleanConstants(definedBooleanConstants), undefinedIntegerConstants(undefinedIntegerConstants), definedIntegerConstants(definedIntegerConstants), undefinedDoubleConstants(undefinedDoubleConstants), definedDoubleConstants(definedDoubleConstants), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables), formulas(formulas), modules(modules), rewardModels(rewardModels), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
             // Now build the mapping from action names to module indices so that the lookup can later be performed quickly.
             for (unsigned int moduleIndex = 0; moduleIndex < this->getNumberOfModules(); moduleIndex++) {
                 Module const& module = this->getModule(moduleIndex);
@@ -101,6 +101,10 @@ namespace storm {
             return this->getGlobalIntegerVariables().size();
         }
         
+        std::map<std::string, storm::expressions::Expression> const& Program::getFormulas() const {
+            return this->formulas;
+        }
+        
         std::size_t Program::getNumberOfModules() const {
             return this->getModules().size();
         }
@@ -175,7 +179,7 @@ namespace storm {
                 newModules.push_back(module.restrictCommands(indexSet));
             }
             
-            return Program(this->getModelType(), this->getUndefinedBooleanConstants(), this->getUndefinedIntegerConstants(), this->getUndefinedDoubleConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+            return Program(this->getModelType(), this->getUndefinedBooleanConstants(), this->getDefinedBooleanConstants(), this->getUndefinedIntegerConstants(), this->getDefinedIntegerConstants(), this->getUndefinedDoubleConstants(), this->getDefinedDoubleConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
         }
         
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 36326b12b..33056833a 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -32,6 +32,7 @@ namespace storm {
              * @param definedDoubleConstants The defined double constants of the program.
              * @param globalBooleanVariables The global boolean variables of the program.
              * @param globalIntegerVariables The global integer variables of the program.
+             * @param formulas The formulas defined in the program.
              * @param modules The modules of the program.
              * @param hasInitialStatesExpression A flag indicating whether the program specifies its initial states via
              * an explicit initial construct.
@@ -43,7 +44,7 @@ namespace storm {
              * @param filename The filename in which the program is defined.
              * @param lineNumber The line number in which the program is defined.
              */
-            Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> const& definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> const& definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> const& definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::map<std::string, storm::expressions::Expression> const& formulas, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Provide default implementations for constructors and assignments.
             Program() = default;
@@ -173,6 +174,13 @@ namespace storm {
              */
             std::size_t getNumberOfGlobalIntegerVariables() const;
 
+            /*!
+             * Retrieves the formulas defined in the program.
+             *
+             * @return The formulas defined in the program.
+             */
+            std::map<std::string, storm::expressions::Expression> const& getFormulas() const;
+            
             /*!
              * Retrieves the number of modules in the program.
              *
@@ -286,12 +294,15 @@ namespace storm {
             // A mapping of (defined) double constants to their values (given as expressions).
             std::map<std::string, storm::expressions::Expression> definedDoubleConstants;
 
-            // A list of global boolean variables.
+            // The global boolean variables.
             std::map<std::string, BooleanVariable> globalBooleanVariables;
             
-            // A list of global integer variables.
+            // The global integer variables.
             std::map<std::string, IntegerVariable> globalIntegerVariables;
             
+            // A mapping of formula names to the corresponding expressions.
+            std::map<std::string, storm::expressions::Expression> formulas;
+            
             // The modules associated with the program.
             std::vector<storm::prism::Module> modules;
             
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index da92823bb..edd400ee2 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -3,25 +3,17 @@
 
 namespace storm {
     namespace prism {
-        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(likelihoodExpression), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments), globalIndex(globalIndex) {
+        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& assignments, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(likelihoodExpression), assignments(assignments), globalIndex(globalIndex) {
             // Nothing to do here.
         }
         
-        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), booleanAssignments(), integerAssignments(), globalIndex(newGlobalIndex) {
-            for (auto const& variableAssignmentPair : update.getBooleanAssignments()) {
+        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), assignments(), globalIndex(newGlobalIndex) {
+            for (auto const& variableAssignmentPair : update.getAssignments()) {
                 auto const& namePair = renaming.find(variableAssignmentPair.first);
                 if (namePair != renaming.end()) {
-                    this->booleanAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
+                    this->assignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
                 } else {
-                    this->booleanAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
-                }
-            }
-            for (auto const& variableAssignmentPair : update.getIntegerAssignments()) {
-                auto const& namePair = renaming.find(variableAssignmentPair.first);
-                if (renaming.count(variableAssignmentPair.first) > 0) {
-                    this->integerAssignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
-                } else {
-                    this->integerAssignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
+                    this->assignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
                 }
             }
             this->likelihoodExpression = update.getLikelihoodExpression().substitute<std::map>(renaming);
@@ -31,35 +23,18 @@ namespace storm {
             return likelihoodExpression;
         }
         
-        std::size_t Update::getNumberOfBooleanAssignments() const {
-            return booleanAssignments.size();
-        }
-        
-        std::size_t Update::getNumberOfIntegerAssignments() const {
-            return integerAssignments.size();
-        }
-        
-        std::map<std::string, storm::prism::Assignment> const& Update::getBooleanAssignments() const {
-            return booleanAssignments;
-        }
-        
-        std::map<std::string, storm::prism::Assignment> const& Update::getIntegerAssignments() const {
-            return integerAssignments;
+        std::size_t Update::getNumberOfAssignments() const {
+            return this->assignments.size();
         }
         
-        storm::prism::Assignment const& Update::getBooleanAssignment(std::string const& variableName) const {
-            auto variableAssignmentPair = booleanAssignments.find(variableName);
-            if (variableAssignmentPair == booleanAssignments.end()) {
-                throw storm::exceptions::OutOfRangeException() << "Cannot find boolean assignment for variable '" << variableName << "' in update " << *this << ".";
-            }
-            
-            return variableAssignmentPair->second;
+        std::map<std::string, storm::prism::Assignment> const& Update::getAssignments() const {
+            return this->assignments;
         }
         
-        storm::prism::Assignment const& Update::getIntegerAssignment(std::string const& variableName) const {
-            auto variableAssignmentPair = integerAssignments.find(variableName);
-            if (variableAssignmentPair == integerAssignments.end()) {
-                throw storm::exceptions::OutOfRangeException() << "Cannot find integer assignment for variable '" << variableName << "' in update " << *this << ".";
+        storm::prism::Assignment const& Update::getAssignment(std::string const& variableName) const {
+            auto variableAssignmentPair = this->getAssignments().find(variableName);
+            if (variableAssignmentPair == this->getAssignments().end()) {
+                throw storm::exceptions::OutOfRangeException() << "Cannot find assignment for variable '" << variableName << "' in update " << *this << ".";
             }
             
             return variableAssignmentPair->second;
@@ -72,17 +47,9 @@ namespace storm {
         std::ostream& operator<<(std::ostream& stream, Update const& update) {
             stream << update.getLikelihoodExpression() << " : ";
             uint_fast64_t i = 0;
-            for (auto const& assignment : update.getBooleanAssignments()) {
-                stream << assignment.second;
-                if (i < update.getBooleanAssignments().size() - 1 || update.getIntegerAssignments().size() > 0) {
-                    stream << " & ";
-                }
-                ++i;
-            }
-            i = 0;
-            for (auto const& assignment : update.getIntegerAssignments()) {
+            for (auto const& assignment : update.getAssignments()) {
                 stream << assignment.second;
-                if (i < update.getIntegerAssignments().size() - 1) {
+                if (i < update.getAssignments().size() - 1) {
                     stream << " & ";
                 }
                 ++i;
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index 4999c04bd..517803c2b 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -20,7 +20,7 @@ namespace storm {
              * @param filename The filename in which the variable is defined.
              * @param lineNumber The line number in which the variable is defined.
              */
-            Update(uint_fast64_t index, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& booleanAssignments, std::map<std::string, storm::prism::Assignment> const& integerAssignments, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Update(uint_fast64_t index, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& assignments, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given update and performs the provided renaming.
@@ -48,46 +48,25 @@ namespace storm {
             storm::expressions::Expression const& getLikelihoodExpression() const;
             
             /*!
-             * Retrieves the number of boolean assignments associated with this update.
+             * Retrieves the number of assignments associated with this update.
              *
-             * @return The number of boolean assignments associated with this update.
+             * @return The number of assignments associated with this update.
              */
-            std::size_t getNumberOfBooleanAssignments() const;
+            std::size_t getNumberOfAssignments() const;
             
             /*!
-             * Retrieves the number of integer assignments associated with this update.
+             * Retrieves a reference to the map of variable names to their respective assignments.
              *
-             * @return The number of integer assignments associated with this update.
+             * @return A reference to the map of variable names to their respective assignments.
              */
-            std::size_t getNumberOfIntegerAssignments() const;
+            std::map<std::string, storm::prism::Assignment> const& getAssignments() const;
             
             /*!
-             * Retrieves a reference to the map of boolean variable names to their respective assignments.
+             * Retrieves a reference to the assignment for the variable with the given name.
              *
-             * @return A reference to the map of boolean variable names to their respective assignments.
+             * @return A reference to the assignment for the variable with the given name.
              */
-            std::map<std::string, storm::prism::Assignment> const& getBooleanAssignments() const;
-            
-            /*!
-             * Retrieves a reference to the map of integer variable names to their respective assignments.
-             *
-             * @return A reference to the map of integer variable names to their respective assignments.
-             */
-            std::map<std::string, storm::prism::Assignment> const& getIntegerAssignments() const;
-            
-            /*!
-             * Retrieves a reference to the assignment for the boolean variable with the given name.
-             *
-             * @return A reference to the assignment for the boolean variable with the given name.
-             */
-            storm::prism::Assignment const& getBooleanAssignment(std::string const& variableName) const;
-            
-            /*!
-             * Retrieves a reference to the assignment for the integer variable with the given name.
-             *
-             * @return A reference to the assignment for the integer variable with the given name.
-             */
-            storm::prism::Assignment const& getIntegerAssignment(std::string const& variableName) const;
+            storm::prism::Assignment const& getAssignment(std::string const& variableName) const;
             
             /*!
              * Retrieves the global index of the update, that is, a unique index over all modules.
@@ -102,11 +81,8 @@ namespace storm {
             // An expression specifying the likelihood of taking this update.
             storm::expressions::Expression likelihoodExpression;
             
-            // A mapping of boolean variable names to their assignments in this update.
-            std::map<std::string, storm::prism::Assignment> booleanAssignments;
-            
-            // A mapping of integer variable names to their assignments in this update.
-            std::map<std::string, storm::prism::Assignment> integerAssignments;
+            // A mapping of variable names to their assignments in this update.
+            std::map<std::string, storm::prism::Assignment> assignments;
             
             // The global index of the update.
             uint_fast64_t globalIndex;
diff --git a/test/functional/parser/ParsePrismTest.cpp b/test/functional/parser/ParsePrismTest.cpp
deleted file mode 100644
index 0a8abb420..000000000
--- a/test/functional/parser/ParsePrismTest.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "gtest/gtest.h"
-#include "storm-config.h"
-#include "src/parser/PrismParser.h"
-//#include "src/utility/IoUtility.h"
-#include "src/ir/Program.h"
-#include "src/adapters/ExplicitModelAdapter.h"
-#include "src/models/Dtmc.h"
-#include "src/models/Mdp.h"
-#include "src/settings/Settings.h"
-#include "src/settings/InternalOptionMemento.h"
-
-TEST(ParsePrismTest, parseCrowds5_5) {
-	storm::settings::InternalOptionMemento deadlockOption("fixDeadlocks", true);
-	ASSERT_TRUE(storm::settings::Settings::getInstance()->isSet("fixDeadlocks"));
-	storm::ir::Program program;
-	ASSERT_NO_THROW(program = storm::parser::PrismParserFromFile(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds5_5.pm"));
-	std::shared_ptr<storm::models::AbstractModel<double>> model = storm::adapters::ExplicitModelAdapter<double>::translateProgram(program);
-    
-	ASSERT_EQ(model->getNumberOfStates(), 8607ull);
-	ASSERT_EQ(model->getNumberOfTransitions(), 15113ull);
-}
-
-TEST(ParsePrismTest, parseTwoDice) {
-	storm::ir::Program program;
-	ASSERT_NO_THROW(program = storm::parser::PrismParserFromFile(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.nm"));
-
-	std::shared_ptr<storm::models::AbstractModel<double>> model = storm::adapters::ExplicitModelAdapter<double>::translateProgram(program, "", "coinflips");
-	
-	ASSERT_EQ(model->getNumberOfStates(), 169ull);
-	ASSERT_EQ(model->as<storm::models::AbstractNondeterministicModel<double>>()->getNumberOfChoices(), 254ull);
-	ASSERT_EQ(model->getNumberOfTransitions(), 436ull);
-}

From cac8a50e90d519bc7fbf555ce37108c0144cabea Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 9 Apr 2014 11:31:58 +0200
Subject: [PATCH 067/147] Further work on PRISM grammar (commit to switch
 workplace).

Former-commit-id: 2969fe50a364096b5ac88e75eb9ff4130f627dd4
---
 src/parser/prismparser/PrismGrammar.cpp | 22 +++++----
 src/parser/prismparser/PrismGrammar.h   | 60 ++++++++++++++++---------
 2 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp
index 7c81b31ce..d52f2b9ae 100644
--- a/src/parser/prismparser/PrismGrammar.cpp
+++ b/src/parser/prismparser/PrismGrammar.cpp
@@ -58,9 +58,21 @@ namespace storm {
                 // Parse a model type.
                 modelTypeDefinition = modelType_;
                 modelTypeDefinition.name("model type");
+
+                programHeader =         modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
+                                >   *(  undefinedConstantDefinition(qi::_r1)
+                                    |   definedConstantDefinition(qi::_r1)
+                                    |   formulaDefinition(qi::_r1)
+                                    |   globalVariableDefinition(qi::_r1)
+                                    );
+                programHeader.name("program header");
+
+                // This block defines all entities that are needed for parsing global variable definitions.
+                globalVariableDefinitionList = *(qi::lit("global") > (booleanVariableDefinition(bind(&GlobalVariableInformation::booleanVariables, qi::_r1), bind(&GlobalVariableInformation::booleanVariableToIndexMap, qi::_r1), true) | integerVariableDefinition(bind(&GlobalVariableInformation::integerVariables, qi::_r1), bind(&GlobalVariableInformation::integerVariableToIndexMap, qi::_r1), true)));
+                globalVariableDefinitionList.name("global variable declaration list");
                 
                 // This block defines all entities that are needed for parsing constant definitions.
-                definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=") > expression > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
                 definedBooleanConstantDefinition.name("defined boolean constant declaration");
                 
                 definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
@@ -77,13 +89,10 @@ namespace storm {
                 definedConstantDefinition.name("defined constant definition");
                 undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3));
                 undefinedConstantDefinition.name("undefined constant definition");
-                constantDefinitionList = *(undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3) | definedConstantDefinition(qi::_r4, qi::_r5, qi::_r6));
-                constantDefinitionList.name("constant definition list");
                 
                 // Parse the ingredients of a probabilistic program.
                 start = (qi::eps >
-                         modelTypeDefinition >
-                         constantDefinitionList(qi::_a, qi::_b, qi::_c, qi::_d, qi::_e, qi::_f) >
+                         programHeader(qi::_a) >
                          formulaDefinitionList >
                          globalVariableDefinitionList(qi::_d) >
                          moduleDefinitionList >
@@ -162,9 +171,6 @@ namespace storm {
                 moduleDefinitionList %= +(moduleDefinition | moduleRenaming);
                 moduleDefinitionList.name("module list");
                 
-                // This block defines all entities that are needed for parsing global variable definitions.
-                globalVariableDefinitionList = *(qi::lit("global") > (booleanVariableDefinition(bind(&GlobalVariableInformation::booleanVariables, qi::_r1), bind(&GlobalVariableInformation::booleanVariableToIndexMap, qi::_r1), true) | integerVariableDefinition(bind(&GlobalVariableInformation::integerVariables, qi::_r1), bind(&GlobalVariableInformation::integerVariableToIndexMap, qi::_r1), true)));
-                globalVariableDefinitionList.name("global variable declaration list");
                 
                 constantBooleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstBooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantBooleanFormulas_.add, qi::_1, qi::_2)];
                 constantBooleanFormulaDefinition.name("constant boolean formula definition");
diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h
index 77a5406fc..785c85e9f 100644
--- a/src/parser/prismparser/PrismGrammar.h
+++ b/src/parser/prismparser/PrismGrammar.h
@@ -16,6 +16,7 @@
 
 namespace qi = boost::spirit::qi;
 namespace phoenix = boost::phoenix;
+namespace prism = storm::prism;
 
 typedef std::string::const_iterator BaseIteratorType;
 typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
@@ -28,13 +29,32 @@ typedef boost::spirit::unused_type Unused;
 
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/Expression.h"
-using namespace storm::prism;
 using namespace storm::expressions;
 
 namespace storm {
     namespace parser {
         namespace prism {
-            class PrismGrammar : public qi::grammar<Iterator, Program(), qi::locals<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, Module>>, Skipper> {
+            class GlobalProgramInformation {
+            public:
+                // Default construct the header information.
+                GlobalProgramInformation() = default;
+                
+                // Members for all essential information that needs to be collected.
+                prism::Program::ModelType modelType;
+                std::set<std::string> undefinedBooleanConstants;
+                std::set<std::string> undefinedIntegerConstants;
+                std::set<std::string> undefinedDoubleConstants;
+                std::map<std::string, storm::expressions::Expression> definedBooleanConstants;
+                std::map<std::string, storm::expressions::Expression> definedIntegerConstants;
+                std::map<std::string, storm::expressions::Expression> definedDoubleConstants;
+                std::map<std::string, storm::expressions::Expression> formulas;
+                std::map<std::string, BooleanVariable> globalBooleanVariables;
+                std::map<std::string, IntegerVariable> globalIntegerVariables;
+                std::map<std::string, Module> modules;
+                std::map<std::string, RewardModel> rewardModels;
+            };
+            
+            class PrismGrammar : public qi::grammar<Iterator, Program(), qi::locals<GlobalProgramInformation>, Skipper> {
             public:
                 /*!
                  * Default constructor that creates an empty and functional grammar.
@@ -43,30 +63,29 @@ namespace storm {
                 
             private:
                 // The starting point of the grammar.
-                // The locals are used for: (a) undefined boolean constants, (b) undefined integer constants, (c) undefined double constants, (d) defined boolean constants, (e) defined integer constants, (f) defined double constants, (g) module name to module map
-                qi::rule<Iterator, Program(), qi::locals<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, storm::expressions::Expression>, std::map<std::string, Module>>, Skipper> start;
+                qi::rule<Iterator, Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
                 
                 // Rules for model type.
                 qi::rule<Iterator, Program::ModelType(), Skipper> modelTypeDefinition;
                 
-                // Rules for constant definitions.
-                qi::rule<Iterator, qi::unused_type(std::set<std::string>&, std::set<std::string>&, std::set<std::string>&, std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&), Skipper> constantDefinitionList;
-                qi::rule<Iterator, qi::unused_type(std::set<std::string>&, std::set<std::string>&, std::set<std::string>&), Skipper> undefinedConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&, std::map<std::string, storm::expressions::Expression>&), Skipper> definedConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::set<std::string>&), Skipper> undefinedBooleanConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::set<std::string>&), Skipper> undefinedIntegerConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::set<std::string>&), Skipper> undefinedDoubleConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> definedBooleanConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> definedIntegerConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> definedDoubleConstantDefinition;
+                // Rules for parsing the program header.
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedBooleanConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedIntegerConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedDoubleConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedBooleanConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedIntegerConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedDoubleConstantDefinition;
                 
                 // Rules for global variable definitions.
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&, std::map<std::string, IntegerVariable>), Skipper> globalVariableDefinitionList;
+                qi::rule<Iterator, qi::unused_type(ProgramHeaderInformation&), Skipper> globalVariableDefinition;
                 
                 // Rules for modules definition.
                 qi::rule<Iterator, std::vector<Module>(), Skipper> moduleDefinitionList;
                 qi::rule<Iterator, Module(), qi::locals<std::map<std::string, BooleanVariable>, std::map<std::string, IntegerVariable>>, Skipper> moduleDefinition;
-                qi::rule<Iterator, Module(std::map<std::string, Module>&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
+                qi::rule<Iterator, Module(GlobalProgramInformation&>, Skipper> moduleRenaming;
                 
                 // Rules for variable definitions.
                 qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&, std::map<std::string, IntegerVariable>&), Skipper> variableDefinition;
@@ -81,18 +100,15 @@ namespace storm {
                 qi::rule<Iterator, Assignment(), Skipper> assignmentDefinition;
                 
                 // Rules for reward definitions.
-                qi::rule<Iterator, std::map<std::string, RewardModel>(), Skipper> rewardDefinitionList;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, RewardModel>&), qi::locals<std::vector<StateReward>, std::vector<TransitionReward>>, Skipper> rewardDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), qi::locals<std::vector<StateReward>, std::vector<TransitionReward>>, Skipper> rewardModelDefinition;
                 qi::rule<Iterator, StateReward(), Skipper> stateRewardDefinition;
                 qi::rule<Iterator, TransitionReward(), Skipper> transitionRewardDefinition;
                 
                 // Rules for label definitions.
-                qi::rule<Iterator, std::map<std::string, storm::expressions::Expression>(), Skipper> labelDefinitionList;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> labelDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> labelDefinition;
                 
                 // Rules for formula definitions.
-                qi::rule<Iterator, std::map<std::string, storm::expressions::Expression>(), Skipper> formulaDefinitionList;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::expressions::Expression>&), Skipper> formulaDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> formulaDefinition;
                 
                 // Rules for identifier parsing.
                 qi::rule<Iterator, std::string(), Skipper> identifier;

From e67eb053095adf5081bc21e0f98e97bcf69de1c6 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 9 Apr 2014 21:14:50 +0200
Subject: [PATCH 068/147] Changed internal data structures of PRISM classes
 slightly. Added classs for certain ingredients that were represented as
 primitives before.

Former-commit-id: bdc61e88a517322c921c6dc2f02df6913cdb8be5
---
 src/parser/PrismParser.cpp              | 190 ++++++++++--------------
 src/parser/prismparser/PrismGrammar.cpp | 188 ++++++++++-------------
 src/parser/prismparser/PrismGrammar.h   | 121 ++++++++++-----
 src/parser/prismparser/Tokens.h         | 113 --------------
 src/storage/prism/Constant.cpp          |  43 ++++++
 src/storage/prism/Constant.h            |  91 ++++++++++++
 src/storage/prism/Formula.cpp           |  26 ++++
 src/storage/prism/Formula.h             |  62 ++++++++
 src/storage/prism/Label.cpp             |  22 +++
 src/storage/prism/Label.h               |  55 +++++++
 src/storage/prism/LocatedInformation.h  |   1 +
 src/storage/prism/Module.cpp            |  53 ++++---
 src/storage/prism/Module.h              |  27 +++-
 src/storage/prism/Program.cpp           | 115 ++++++--------
 src/storage/prism/Program.h             | 154 ++++++++-----------
 src/storage/prism/Update.cpp            |  29 ++--
 src/storage/prism/Update.h              |  26 ++--
 src/storm.cpp                           |   3 +-
 18 files changed, 726 insertions(+), 593 deletions(-)
 delete mode 100644 src/parser/prismparser/Tokens.h
 create mode 100644 src/storage/prism/Constant.cpp
 create mode 100644 src/storage/prism/Constant.h
 create mode 100644 src/storage/prism/Formula.cpp
 create mode 100644 src/storage/prism/Formula.h
 create mode 100644 src/storage/prism/Label.cpp
 create mode 100644 src/storage/prism/Label.h

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 587c91dc8..98f58f208 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -1,13 +1,4 @@
-/*
- * PrismParser.cpp
- *
- *  Created on: 11.01.2013
- *      Author: chris
- */
-
-#include "PrismParser.h"
-
-#include "src/utility/OsDetection.h"
+#include "src/parser/PrismParser.h"
 
 #include "src/parser/prismparser/PrismGrammar.h"
 
@@ -21,108 +12,87 @@
 
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "log4cplus/consoleappender.h"
+#include "log4cplus/fileappender.h"
+log4cplus::Logger logger;
 
 namespace storm {
-namespace parser {
-
-/*!
- * Opens the given file for parsing, invokes the helper function to parse the actual content and
- * closes the file properly, even if an exception is thrown in the parser. In this case, the
- * exception is passed on to the caller.
- */
-storm::ir::Program PrismParserFromFile(std::string const& filename) {
-	// Open file and initialize result.
-	std::ifstream inputFileStream(filename, std::ios::in);
-	storm::ir::Program result;
-
-	// Now try to parse the contents of the file.
-	try {
-		result = PrismParser(inputFileStream, filename);
-	} catch(std::exception& e) {
-		// In case of an exception properly close the file before passing exception.
-		inputFileStream.close();
-		throw e;
-	}
-
-	// Close the stream in case everything went smoothly and return result.
-	inputFileStream.close();
-	return result;
-}
-
-/*!
- * Passes iterators to the input stream to the Boost spirit parser and thereby parses the input.
- * If the parser throws an expectation failure exception, i.e. expected input different than the one
- * provided, this is caught and displayed properly before the exception is passed on.
- */
-storm::ir::Program PrismParser(std::istream& inputStream, std::string const& filename) {
-	// Prepare iterators to input.
-	// TODO: Right now, this parses the whole contents of the file into a string first.
-	// While this is usually not necessary, because there exist adapters that make an input stream
-	// iterable in both directions without storing it into a string, using the corresponding
-	// Boost classes gives an awful output under valgrind and is thus disabled for the time being.
-	std::string fileContent((std::istreambuf_iterator<char>(inputStream)), (std::istreambuf_iterator<char>()));
-	BaseIteratorType stringIteratorBegin = fileContent.begin();
-	BaseIteratorType stringIteratorEnd = fileContent.end();
-	PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename);
-	PositionIteratorType positionIteratorBegin2(stringIteratorBegin, stringIteratorEnd, filename);
-	PositionIteratorType positionIteratorEnd;
-
-	// Prepare resulting intermediate representation of input.
-	storm::ir::Program result;
-
-	// In order to instantiate the grammar, we have to pass the type of the skipping parser.
-	// As this is more complex, we let Boost figure out the actual type for us.
-	prism::PrismGrammar grammar;
-	try {
-		// Now parse the content using phrase_parse in order to be able to supply a skipping parser.
-		// First run.
-		LOG4CPLUS_INFO(logger, "Start parsing...");
-		qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
-		grammar.prepareForSecondRun();
-		result = storm::ir::Program();
-		LOG4CPLUS_INFO(logger, "Start second parsing run...");
-		// Second run.
-		qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
-		LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result.toString());
-		// Reset grammars.
-		grammar.resetGrammars();
-	} catch(const qi::expectation_failure<PositionIteratorType>& e) {
-		// If the parser expected content different than the one provided, display information
-		// about the location of the error.
-		const boost::spirit::classic::file_position_base<std::string>& pos = e.first.get_position();
-
-		// Construct the error message including a caret display of the position in the
-		// erroneous line.
-		std::stringstream msg;
-		std::string line = e.first.get_currentline();
-		while (line.find('\t') != std::string::npos) line.replace(line.find('\t'),1," ");
-		msg << pos.file << ", line " << pos.line << ", column " << pos.column
+    namespace parser {
+        storm::prism::Program PrismParserFromFile(std::string const& filename) {
+            // Open file and initialize result.
+            std::ifstream inputFileStream(filename, std::ios::in);
+            storm::prism::Program result;
+            
+            // Now try to parse the contents of the file.
+            try {
+                result = PrismParser(inputFileStream, filename);
+            } catch(std::exception& e) {
+                // In case of an exception properly close the file before passing exception.
+                inputFileStream.close();
+                throw e;
+            }
+            
+            // Close the stream in case everything went smoothly and return result.
+            inputFileStream.close();
+            return result;
+        }
+        
+        storm::prism::Program PrismParser(std::istream& inputStream, std::string const& filename) {
+            // Prepare iterators to input.
+            // TODO: Right now, this parses the whole contents of the file into a string first.
+            // While this is usually not necessary, because there exist adapters that make an input stream
+            // iterable in both directions without storing it into a string, using the corresponding
+            // Boost classes gives an awful output under valgrind and is thus disabled for the time being.
+            std::string fileContent((std::istreambuf_iterator<char>(inputStream)), (std::istreambuf_iterator<char>()));
+            BaseIteratorType stringIteratorBegin = fileContent.begin();
+            BaseIteratorType stringIteratorEnd = fileContent.end();
+            PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename);
+            PositionIteratorType positionIteratorBegin2(stringIteratorBegin, stringIteratorEnd, filename);
+            PositionIteratorType positionIteratorEnd;
+            
+            // Prepare resulting intermediate representation of input.
+            storm::prism::Program result;
+            
+            // In order to instantiate the grammar, we have to pass the type of the skipping parser.
+            // As this is more complex, we let Boost figure out the actual type for us.
+            storm::parser::prism::PrismGrammar grammar;
+            try {
+                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
+                // First run.
+                LOG4CPLUS_INFO(logger, "Start parsing...");
+                qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
+                LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result);
+
+            } catch(const qi::expectation_failure<PositionIteratorType>& e) {
+                // If the parser expected content different than the one provided, display information
+                // about the location of the error.
+                const boost::spirit::classic::file_position_base<std::string>& pos = e.first.get_position();
+                
+                // Construct the error message including a caret display of the position in the
+                // erroneous line.
+                std::stringstream msg;
+                std::string line = e.first.get_currentline();
+                while (line.find('\t') != std::string::npos) line.replace(line.find('\t'),1," ");
+                msg << pos.file << ", line " << pos.line << ", column " << pos.column
 				<< ": parse error: expected " << e.what_ << std::endl << "\t"
 				<< line << std::endl << "\t";
-		int i = 0;
-		for (i = 1; i < pos.column; ++i) {
-			msg << "-";
-		}
-		msg << "^";
-		for (; i < 80; ++i) {
-			msg << "-";
-		}
-		msg << std::endl;
-
-		std::cerr << msg.str();
-		
-		// Reset grammars in any case.
-		grammar.resetGrammars();
-
-		// Now propagate exception.
-		throw storm::exceptions::WrongFormatException() << msg.str();
-	}
-
-	return result;
-}
-
-} // namespace parser
-
+                int i = 0;
+                for (i = 1; i < pos.column; ++i) {
+                    msg << "-";
+                }
+                msg << "^";
+                for (; i < 80; ++i) {
+                    msg << "-";
+                }
+                msg << std::endl;
+                
+                std::cerr << msg.str();
+                
+                // Now propagate exception.
+                throw storm::exceptions::WrongFormatException() << msg.str();
+            }
+            
+            return result;
+        }
+    } // namespace parser
 } // namespace storm
diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp
index d52f2b9ae..72b7a40b8 100644
--- a/src/parser/prismparser/PrismGrammar.cpp
+++ b/src/parser/prismparser/PrismGrammar.cpp
@@ -46,146 +46,108 @@ namespace storm {
                 atomicNumericalExpression %= minMaxExpression | floorCeilExpression | numericalVariableExpression | qi::lit("(") >> numericalExpression >> qi::lit(")");
                 atomicNumericalExpression.name("numerical expression");
                 
-                minMaxExpression %= ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(",") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]];
+                minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(",") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]];
                 minMaxExpression.name("min/max expression");
                 
-                floorCeilExpression %= ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]];
+                floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]];
                 floorCeilExpression.name("integer floor/ceil expression");
 
                 numericalVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleVariable, qi::_1)];
                 numericalVariableExpression.name("numerical variable");
                 
-                // Parse a model type.
                 modelTypeDefinition = modelType_;
                 modelTypeDefinition.name("model type");
+                
+                undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r1) | undefinedDoubleConstantDefinition(qi::_r1));
+                undefinedConstantDefinition.name("undefined constant definition");
 
-                programHeader =         modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
-                                >   *(  undefinedConstantDefinition(qi::_r1)
-                                    |   definedConstantDefinition(qi::_r1)
-                                    |   formulaDefinition(qi::_r1)
-                                    |   globalVariableDefinition(qi::_r1)
-                                    );
-                programHeader.name("program header");
+                undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, phoenix::bind(&GlobalProgramInformation::undefinedBooleanConstants, qi::_r1), qi::_1)];
+                undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
 
-                // This block defines all entities that are needed for parsing global variable definitions.
-                globalVariableDefinitionList = *(qi::lit("global") > (booleanVariableDefinition(bind(&GlobalVariableInformation::booleanVariables, qi::_r1), bind(&GlobalVariableInformation::booleanVariableToIndexMap, qi::_r1), true) | integerVariableDefinition(bind(&GlobalVariableInformation::integerVariables, qi::_r1), bind(&GlobalVariableInformation::integerVariableToIndexMap, qi::_r1), true)));
-                globalVariableDefinitionList.name("global variable declaration list");
+                undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, phoenix::bind(&GlobalProgramInformation::undefinedIntegerConstants, qi::_r1), qi::_1)];
+                undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
                 
-                // This block defines all entities that are needed for parsing constant definitions.
-                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+                undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, phoenix::bind(&GlobalProgramInformation::undefinedDoubleConstants, qi::_r1), qi::_1)];
+                undefinedDoubleConstantDefinition.name("undefined double constant definition");
+
+                definedConstantDefinition %= (definedBooleanConstantDefinition(qi::_r1) | definedIntegerConstantDefinition(qi::_r1) | definedDoubleConstantDefinition(qi::_r1));
+                definedConstantDefinition.name("defined constant definition");
+
+                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedBooleanConstant, phoenix::bind(&GlobalProgramInformation::definedBooleanConstants, qi::_r1), qi::_1, qi::_2)];
                 definedBooleanConstantDefinition.name("defined boolean constant declaration");
-                
-                definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+
+                definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedIntegerConstant, phoenix::bind(&GlobalProgramInformation::definedIntegerConstants, qi::_r1), qi::_1, qi::_2)];
                 definedIntegerConstantDefinition.name("defined integer constant declaration");
-                definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
+
+                definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedDoubleConstant, phoenix::bind(&GlobalProgramInformation::definedDoubleConstants, qi::_r1), qi::_1, qi::_2)];
                 definedDoubleConstantDefinition.name("defined double constant declaration");
-                undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, this, qi::_1, qi::_r1)];
-                undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
-                undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, this, qi::_1, qi::_r1)];
-                undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
-                undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, this, qi::_1, qi::_r1)];
-                undefinedDoubleConstantDefinition.name("undefined double constant definition");
-                definedConstantDefinition %= (definedBooleanConstantDefinition(qi::_r1) | definedIntegerConstantDefinition(qi::_r2) | definedDoubleConstantDefinition(qi::_r3));
-                definedConstantDefinition.name("defined constant definition");
-                undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3));
-                undefinedConstantDefinition.name("undefined constant definition");
                 
-                // Parse the ingredients of a probabilistic program.
-                start = (qi::eps >
-                         programHeader(qi::_a) >
-                         formulaDefinitionList >
-                         globalVariableDefinitionList(qi::_d) >
-                         moduleDefinitionList >
-                         rewardDefinitionList(qi::_e) >
-                         labelDefinitionList(qi::_f))[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2, qi::_e, qi::_f)];
-                start.name("probabilistic program declaration");
-
+                formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addFormula, phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1, qi::_2)];
+                formulaDefinition.name("formula definition");
                 
-                labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> FreeIdentifierGrammar::instance(this->state) >> -qi::lit("\"") >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))
-                [phoenix::bind(&PrismGrammar::addLabel, this, qi::_1, qi::_2, qi::_r1)];
-                labelDefinition.name("label declaration");
-                labelDefinitionList %= *labelDefinition(qi::_r1);
-                labelDefinitionList.name("label declaration list");
+                globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1)) | integerVariableDefinition(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1))));
+                globalVariableDefinition.name("global variable declaration list");
                 
-                // This block defines all entities that are needed for parsing a reward model.
-                stateRewardDefinition = (BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::bind(&createStateReward, qi::_1, qi::_2)];
+                programHeader =         modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
+                                >   *(  undefinedConstantDefinition(qi::_r1)
+                                    |   definedConstantDefinition(qi::_r1)
+                                    |   formulaDefinition(qi::_r1)
+                                    |   globalVariableDefinition(qi::_r1)
+                                    );
+                programHeader.name("program header");
+ 
+                rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"")
+                                         > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)]
+                                            |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
+                                            )
+                                         >> qi::lit("endrewards"))[phoenix::bind(&PrismGrammar::addRewardModel, phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_r1), qi::_1, qi::_a, qi::_b)];
+                rewardModelDefinition.name("reward model definition");
+                
+                stateRewardDefinition = (booleanExpression > qi::lit(":") > numericalExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createStateReward, qi::_1, qi::_2)];
                 stateRewardDefinition.name("state reward definition");
-                transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::bind(&createTransitionReward, qi::_a, qi::_2, qi::_3)];
+                
+                transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > numericalExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createTransitionReward, qi::_a, qi::_2, qi::_3)];
                 transitionRewardDefinition.name("transition reward definition");
-                rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > FreeIdentifierGrammar::instance(this->state) > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))
-                [phoenix::bind(&createRewardModel, qi::_1, qi::_a, qi::_b, qi::_r1)];
-                rewardDefinition.name("reward definition");
-                rewardDefinitionList = *rewardDefinition(qi::_r1);
-                rewardDefinitionList.name("reward definition list");
-                
-                commandName %= this->state->commandNames_;
-                commandName.name("command name");
-                unassignedLocalBooleanVariableName %= (this->state->localBooleanVariables_ | this->state->globalBooleanVariables_) - this->state->assignedBooleanVariables_;
-                unassignedLocalBooleanVariableName.name("unassigned local/global boolean variable");
-                unassignedLocalIntegerVariableName %= (this->state->localIntegerVariables_ | this->state->globalIntegerVariables_) - this->state->assignedIntegerVariables_;
-                unassignedLocalIntegerVariableName.name("unassigned local/global integer variable");
-                
-                // This block defines all entities that are needed for parsing a single command.
-                assignmentDefinition =
-                (qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismGrammar::addIntegerAssignment, this, qi::_1, qi::_2, qi::_r2)] |
-                (qi::lit("(") >> unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismGrammar::addBooleanAssignment, this, qi::_1, qi::_2, qi::_r1)];
+
+                labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > booleanExpression >> qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addLabel, phoenix::bind(&GlobalProgramInformation::labels, qi::_r1), qi::_1, qi::_2)];
+                labelDefinition.name("label definition");
+
+                assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_pass = phoenix::bind(&PrismGrammar::addAssignment, qi::_r1, qi::_1, qi::_2)];
                 assignmentDefinition.name("assignment");
-                assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&";
+                assignmentDefinitionList = assignmentDefinition(qi::_r1) % "&";
                 assignmentDefinitionList.name("assignment list");
-                updateDefinition = (((ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(":"))
-                                     | qi::attr(std::shared_ptr<BaseExpression>(new storm::ir::expressions::DoubleLiteralExpression(1))))[phoenix::clear(phoenix::ref(this->state->assignedBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedIntegerVariables_))]
-                                    >> assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, this, qi::_1, qi::_a, qi::_b)];
+                
+                moduleDefinitionList %= +(moduleDefinition(qi::_r1) | moduleRenaming(qi::_r1));
+                moduleDefinitionList.name("module list");
+
+                updateDefinition = (((numericalExpression >> qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList(qi::_a))[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, qi::_1, qi::_a)];
                 updateDefinition.name("update");
-                updateListDefinition = +updateDefinition % "+";
+                
+                updateListDefinition %= +updateDefinition % "+";
                 updateListDefinition.name("update list");
-                commandDefinition = (
-                                     qi::lit("[") > -(
-                                                      (FreeIdentifierGrammar::instance(this->state)[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]
-                                                      ) > qi::lit("]") > BooleanExpressionGrammar::instance(this->state) > qi::lit("->") > updateListDefinition > qi::lit(";")
-                                     )[qi::_val = phoenix::bind(&PrismGrammar::createCommand, this, qi::_a, qi::_2, qi::_3)];
-                commandDefinition.name("command");
-                
-                // This block defines all entities that are needed for parsing variable definitions.
-                booleanVariableDefinition = (FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct<std::shared_ptr<BaseExpression>>(qi::_1)]) > qi::lit(";"))
-                [phoenix::bind(&PrismGrammar::createBooleanVariable, this, qi::_1, qi::_b, qi::_r1, qi::_r2, qi::_r3)];
-                booleanVariableDefinition.name("boolean variable declaration");
-                
-                integerVariableDefinition = (FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("..") > ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("]") > -(qi::lit("init") > ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct<std::shared_ptr<BaseExpression>>(qi::_1)]) > qi::lit(";"))
-                [phoenix::bind(&PrismGrammar::createIntegerVariable, this, qi::_1, qi::_2, qi::_3, qi::_b, qi::_r1, qi::_r2, qi::_r3)];
-                integerVariableDefinition.name("integer variable declaration");
-                variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3, false) | integerVariableDefinition(qi::_r2, qi::_r4, false));
-                variableDefinition.name("variable declaration");
                 
-                // This block defines all entities that are needed for parsing a module.
-                moduleDefinition = (qi::lit("module") >> FreeIdentifierGrammar::instance(this->state)[phoenix::bind(&VariableState::clearLocalVariables, *this->state)]
-                                    >> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule"))
-                [qi::_val = phoenix::bind(&PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)];
-                
-                moduleDefinition.name("module");
-                moduleRenaming = (qi::lit("module")	>> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=")
-                                  > this->state->moduleNames_ > qi::lit("[") > *(
-                                                                                 (IdentifierGrammar::instance(this->state) > qi::lit("=") > IdentifierGrammar::instance(this->state) >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))]
-                                                                                 ) > qi::lit("]") > qi::lit("endmodule"))
-                [qi::_val = phoenix::bind(&PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)];
-                moduleRenaming.name("renamed module");
-                moduleDefinitionList %= +(moduleDefinition | moduleRenaming);
-                moduleDefinitionList.name("module list");
+                commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createCommand, qi::_a, qi::_2, qi::_3)];
+                commandDefinition.name("command definition");
+
+                booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > booleanExpression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addBooleanVariable, qi::_r1, qi::_1, qi::_2)];
+                booleanVariableDefinition.name("boolean variable definition");
                 
+                integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")) > numericalExpression[qi::_a = qi::_1] > qi::lit("..") > numericalExpression > qi::lit("]") > -(qi::lit("init") > numericalExpression[qi::_a = qi::_1]) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addIntegerVariable, qi::_r1, qi::_1, qi::_2, qi::_3, qi::_a)];
+                integerVariableDefinition.name("integer variable definition");
                 
-                constantBooleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstBooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantBooleanFormulas_.add, qi::_1, qi::_2)];
-                constantBooleanFormulaDefinition.name("constant boolean formula definition");
-                booleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->booleanFormulas_.add, qi::_1, qi::_2)];
-                booleanFormulaDefinition.name("boolean formula definition");
-                constantIntegerFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantIntegerFormulas_.add, qi::_1, qi::_2)];
-                constantIntegerFormulaDefinition.name("constant integer formula definition");
-                integerFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> IntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerFormulas_.add, qi::_1, qi::_2)];
-                integerFormulaDefinition.name("integer formula definition");
-                constantDoubleFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantDoubleFormulas_.add, qi::_1, qi::_2)];
-                constantDoubleFormulaDefinition.name("constant double formula definition");
-                formulaDefinition = constantBooleanFormulaDefinition | booleanFormulaDefinition | constantIntegerFormulaDefinition | integerFormulaDefinition | constantDoubleFormulaDefinition;
-                formulaDefinition.name("formula definition");
-                formulaDefinitionList = *formulaDefinition;
-                formulaDefinitionList.name("formula definition list");
+                variableDefinition = (booleanVariableDefinition(qi::_r1) | integerVariableDefinition(qi::_r2));
+                variableDefinition.name("variable declaration");
+
+                moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createModule, qi::_1, qi::_a, qi::_b, qi::_2)];
+                moduleDefinition.name("module definition");
+                
+                moduleRenaming = ((qi::lit("module")	>> identifier >> qi::lit("=")) > identifier > qi::lit("[")
+                                  > ((identifier > qi::lit("=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))] % ",") > qi::lit("]")
+                                  > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createRenamedModule, qi::_1, qi::_2, qi::_a, qi::_r1)];
+                moduleRenaming.name("module definition via renaming");
+                
+                start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(rewardModelDefinition(qi::_a) | labelDefinition(qi::_a)))[qi::_val = phoenix::bind(&PrismGrammar::createProgram, qi::_a, qi::_1)];
+                start.name("probabilistic program");
             }
         } // namespace prism
     } // namespace parser
diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h
index 785c85e9f..d51ee4f04 100644
--- a/src/parser/prismparser/PrismGrammar.h
+++ b/src/parser/prismparser/PrismGrammar.h
@@ -16,7 +16,6 @@
 
 namespace qi = boost::spirit::qi;
 namespace phoenix = boost::phoenix;
-namespace prism = storm::prism;
 
 typedef std::string::const_iterator BaseIteratorType;
 typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
@@ -25,22 +24,51 @@ typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_
 typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
 typedef boost::spirit::unused_type Unused;
 
-#include "src/parser/prismparser/Tokens.h"
-
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/Expression.h"
-using namespace storm::expressions;
 
 namespace storm {
     namespace parser {
         namespace prism {
+            
+            struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
+                modelTypeStruct() {
+                    add
+                    ("dtmc", storm::prism::Program::ModelType::DTMC)
+                    ("ctmc", storm::prism::Program::ModelType::CTMC)
+                    ("mdp", storm::prism::Program::ModelType::MDP)
+                    ("ctmdp", storm::prism::Program::ModelType::CTMDP)
+                    ("ma", storm::prism::Program::ModelType::MA);
+                }
+            };
+            
+            struct keywordsStruct : qi::symbols<char, unsigned> {
+                keywordsStruct() {
+                    add
+                    ("dtmc", 1)
+                    ("ctmc", 2)
+                    ("mdp", 3)
+                    ("ctmdp", 4)
+                    ("ma", 5)
+                    ("const", 6)
+                    ("int", 7)
+                    ("bool", 8)
+                    ("module", 9)
+                    ("endmodule", 10)
+                    ("rewards", 11)
+                    ("endrewards", 12)
+                    ("true", 13)
+                    ("false", 14);
+                }
+            };
+            
             class GlobalProgramInformation {
             public:
                 // Default construct the header information.
                 GlobalProgramInformation() = default;
                 
                 // Members for all essential information that needs to be collected.
-                prism::Program::ModelType modelType;
+                storm::prism::Program::ModelType modelType;
                 std::set<std::string> undefinedBooleanConstants;
                 std::set<std::string> undefinedIntegerConstants;
                 std::set<std::string> undefinedDoubleConstants;
@@ -48,13 +76,18 @@ namespace storm {
                 std::map<std::string, storm::expressions::Expression> definedIntegerConstants;
                 std::map<std::string, storm::expressions::Expression> definedDoubleConstants;
                 std::map<std::string, storm::expressions::Expression> formulas;
-                std::map<std::string, BooleanVariable> globalBooleanVariables;
-                std::map<std::string, IntegerVariable> globalIntegerVariables;
-                std::map<std::string, Module> modules;
-                std::map<std::string, RewardModel> rewardModels;
+                std::map<std::string, storm::prism::BooleanVariable> globalBooleanVariables;
+                std::map<std::string, storm::prism::IntegerVariable> globalIntegerVariables;
+                std::map<std::string, storm::prism::Module> modules;
+                std::map<std::string, storm::prism::RewardModel> rewardModels;
+                std::map<std::string, storm::expressions::Expression> labels;
+                
+                // Counters to provide unique indexing for commands and updates.
+                uint_fast64_t currentCommandIndex;
+                uint_fast64_t currentUpdateIndex;
             };
             
-            class PrismGrammar : public qi::grammar<Iterator, Program(), qi::locals<GlobalProgramInformation>, Skipper> {
+            class PrismGrammar : public qi::grammar<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> {
             public:
                 /*!
                  * Default constructor that creates an empty and functional grammar.
@@ -63,46 +96,48 @@ namespace storm {
                 
             private:
                 // The starting point of the grammar.
-                qi::rule<Iterator, Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
+                qi::rule<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
                 
                 // Rules for model type.
-                qi::rule<Iterator, Program::ModelType(), Skipper> modelTypeDefinition;
+                qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
                 
                 // Rules for parsing the program header.
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedConstantDefinition;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedBooleanConstantDefinition;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedIntegerConstantDefinition;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedDoubleConstantDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedConstantDefinition;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedBooleanConstantDefinition;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedIntegerConstantDefinition;
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedDoubleConstantDefinition;
                 
                 // Rules for global variable definitions.
-                qi::rule<Iterator, qi::unused_type(ProgramHeaderInformation&), Skipper> globalVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalBooleanVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalIntegerVariableDefinition;
                 
                 // Rules for modules definition.
-                qi::rule<Iterator, std::vector<Module>(), Skipper> moduleDefinitionList;
-                qi::rule<Iterator, Module(), qi::locals<std::map<std::string, BooleanVariable>, std::map<std::string, IntegerVariable>>, Skipper> moduleDefinition;
-                qi::rule<Iterator, Module(GlobalProgramInformation&>, Skipper> moduleRenaming;
+                qi::rule<Iterator, std::vector<storm::prism::Module>(GlobalProgramInformation&), Skipper> moduleDefinitionList;
+                qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, storm::prism::BooleanVariable>, std::map<std::string, storm::prism::IntegerVariable>>, Skipper> moduleDefinition;
+                qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
                 
                 // Rules for variable definitions.
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&, std::map<std::string, IntegerVariable>&), Skipper> variableDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, BooleanVariable>&), Skipper> booleanVariableDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, IntegerVariable>&), Skipper> integerVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::BooleanVariable>&, std::map<std::string, storm::prism::IntegerVariable>&), Skipper> variableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::BooleanVariable>&), Skipper> booleanVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::IntegerVariable>&), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
                 
                 // Rules for command definitions.
-                qi::rule<Iterator, Command(), qi::locals<std::string>, Skipper> commandDefinition;
-                qi::rule<Iterator, std::vector<Update>(), Skipper> updateListDefinition;
-                qi::rule<Iterator, Update(), qi::locals<std::map<std::string, Assignment>>, Skipper> updateDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, Assignment>&), Skipper> assignmentDefinitionList;
-                qi::rule<Iterator, Assignment(), Skipper> assignmentDefinition;
+                qi::rule<Iterator, storm::prism::Command(), qi::locals<std::string>, Skipper> commandDefinition;
+                qi::rule<Iterator, std::vector<storm::prism::Update>(), Skipper> updateListDefinition;
+                qi::rule<Iterator, storm::prism::Update(), qi::locals<std::map<std::string, storm::prism::Assignment>>, Skipper> updateDefinition;
+                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::Assignment>&), Skipper> assignmentDefinitionList;
+                qi::rule<Iterator, storm::prism::Assignment(std::map<std::string, storm::prism::Assignment>&), Skipper> assignmentDefinition;
                 
                 // Rules for reward definitions.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), qi::locals<std::vector<StateReward>, std::vector<TransitionReward>>, Skipper> rewardModelDefinition;
-                qi::rule<Iterator, StateReward(), Skipper> stateRewardDefinition;
-                qi::rule<Iterator, TransitionReward(), Skipper> transitionRewardDefinition;
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), qi::locals<std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
+                qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
+                qi::rule<Iterator, storm::prism::TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
                 
                 // Rules for label definitions.
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> labelDefinition;
@@ -130,17 +165,35 @@ namespace storm {
                 qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
                 
-                // Parsers that recognize special keywords and operations.
+                // Parsers that recognize special keywords and model types.
                 storm::parser::prism::keywordsStruct keywords_;
                 storm::parser::prism::modelTypeStruct modelType_;
-                storm::parser::prism::BinaryRelationOperatorStruct relationOperator_;
-                storm::parser::prism::BinaryBooleanOperatorStruct binaryBooleanOperator_;
-                storm::parser::prism::UnaryBooleanOperatorStruct unaryBooleanOperator_;
-                storm::parser::prism::BinaryNumericalOperatorStruct binaryNumericalOperator_;
-                storm::parser::prism::UnaryNumericalOperatorStruct unaryNumericalOperator_;
                 
                 // Helper methods that add data to data structures.
+                static bool addUndefinedBooleanConstant(std::set<std::string>& undefinedBooleanConstants, std::string const& newUndefinedBooleanConstant);
+                static bool addUndefinedIntegerConstant(std::set<std::string>& undefinedIntegerConstants, std::string const& newUndefinedIntegerConstant);
+                static bool addUndefinedDoubleConstant(std::set<std::string>& undefinedDoubleConstants, std::string const& newUndefinedDoubleConstant);
                 
+                static bool addDefinedBooleanConstant(std::map<std::string, storm::expressions::Expression>& definedBooleanConstants, std::string const& newDefinedBooleanConstant, storm::expressions::Expression expression);
+                static bool addDefinedIntegerConstant(std::map<std::string, storm::expressions::Expression>& definedIntegerConstants, std::string const& newDefinedIntegerConstant, storm::expressions::Expression expression);
+                static bool addDefinedDoubleConstant(std::map<std::string, storm::expressions::Expression>& definedDoubleConstants, std::string const& newDefinedDoubleConstant, storm::expressions::Expression expression);
+
+                static bool addFormula(std::map<std::string, storm::expressions::Expression>& formulas, std::string const& formulaName, storm::expressions::Expression expression);
+                
+                static storm::prism::RewardModel addRewardModel(std::map<std::string, storm::prism::RewardModel>& rewardModels, std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards);
+                static storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression);
+                static storm::prism::TransitionReward createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression);
+                
+                static bool addLabel(std::map<std::string, storm::expressions::Expression>& labels, std::string const& labelName, storm::expressions::Expression expression);
+                
+                static bool addAssignment(std::map<std::string, storm::prism::Assignment>& assignments, std::string const& variableName, storm::expressions::Expression assignedExpression);
+                static storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::map<std::string, storm::prism::Assignment>& assignments);
+                static storm::prism::Command createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates);
+                static bool addBooleanVariable(std::map<std::string, storm::prism::BooleanVariable>& booleanVariables, std::string const& variableName, storm::expressions::Expression initialValueExpression);
+                static bool addIntegerVariable(std::map<std::string, storm::prism::IntegerVariable>& integerVariables, std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression);
+                static storm::prism::Module createModule(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands);
+                static storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation const& globalProgramInformation);
+                static storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation, std::vector<storm::prism::Module> const& modules);
             };
         } // namespace prism
     } // namespace parser
diff --git a/src/parser/prismparser/Tokens.h b/src/parser/prismparser/Tokens.h
deleted file mode 100644
index 866bbbf24..000000000
--- a/src/parser/prismparser/Tokens.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef STORM_PARSER_PRISMPARSER_TOKENS_H_
-#define	STORM_PARSER_PRISMPARSER_TOKENS_H_
-
-#include "src/storage/prism/Program.h"
-#include "src/storage/expressions/Expressions.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            /*!
-             * A structure mapping the textual representation of a model type to the model type
-             * representation of the intermediate representation.
-             */
-            struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
-                modelTypeStruct() {
-                    add
-                    ("dtmc", storm::prism::Program::ModelType::DTMC)
-                    ("ctmc", storm::prism::Program::ModelType::CTMC)
-                    ("mdp", storm::prism::Program::ModelType::MDP)
-                    ("ctmdp", storm::prism::Program::ModelType::CTMDP)
-                    ("ma", storm::prism::Program::ModelType::MA);
-                }
-            };
-            
-            /*!
-             * A structure defining the keywords that are not allowed to be chosen as identifiers.
-             */
-            struct keywordsStruct : qi::symbols<char, unsigned> {
-                keywordsStruct() {
-                    add
-                    ("dtmc", 1)
-                    ("ctmc", 2)
-                    ("mdp", 3)
-                    ("ctmdp", 4)
-                    ("ma", 5)
-                    ("const", 6)
-                    ("int", 7)
-                    ("bool", 8)
-                    ("module", 9)
-                    ("endmodule", 10)
-                    ("rewards", 11)
-                    ("endrewards", 12)
-                    ("true", 13)
-                    ("false", 14);
-                }
-            };
-            
-            /*!
-             * A structure mapping the textual representation of binary relations to the corresponding enum values.
-             */
-            struct BinaryRelationOperatorStruct : qi::symbols<char, storm::expressions::BinaryRelationExpression::RelationType> {
-                BinaryRelationOperatorStruct() {
-                    add
-                    ("=", storm::expressions::BinaryRelationExpression::RelationType::Equal)
-                    ("!=", storm::expressions::BinaryRelationExpression::RelationType::NotEqual)
-                    ("<", storm::expressions::BinaryRelationExpression::RelationType::Less)
-                    ("<=", storm::expressions::BinaryRelationExpression::RelationType::LessOrEqual)
-                    (">", storm::expressions::BinaryRelationExpression::RelationType::Greater)
-                    (">=", storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual);
-                }
-            };
-            
-            /*!
-             * A structure mapping the textual representation of binary operators to the corresponding enum values.
-             */
-            struct BinaryBooleanOperatorStruct : qi::symbols<char, storm::expressions::BinaryBooleanFunctionExpression::OperatorType> {
-                BinaryBooleanOperatorStruct() {
-                    add
-                    ("&", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And)
-                    ("|", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or)
-                    ("=>", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Implies)
-                    ("<=>", storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff);
-                }
-            };
-
-            /*!
-             * A structure mapping the textual representation of binary operators to the corresponding enum values.
-             */
-            struct UnaryBooleanOperatorStruct : qi::symbols<char, storm::expressions::UnaryBooleanFunctionExpression::OperatorType> {
-                UnaryBooleanOperatorStruct() {
-                    add
-                    ("!", storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not);
-                }
-            };
-            
-            /*!
-             * A structure mapping the textual representation of binary boolean operators to the corresponding enum values.
-             */
-            struct BinaryNumericalOperatorStruct : qi::symbols<char, storm::expressions::BinaryNumericalFunctionExpression::OperatorType> {
-                BinaryNumericalOperatorStruct() {
-                    add
-                    ("+", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus)
-                    ("-", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Minus)
-                    ("*", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times)
-                    ("/", storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide);
-                }
-            };
-            
-            /*!
-             * A structure mapping the textual representation of binary operators to the corresponding enum values.
-             */
-            struct UnaryNumericalOperatorStruct : qi::symbols<char, storm::expressions::UnaryNumericalFunctionExpression::OperatorType> {
-                UnaryNumericalOperatorStruct() {
-                    add
-                    ("!", storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus);
-                }
-            };
-        }
-    }
-}
-
-#endif	/* STORM_PARSER_PRISMPARSER_TOKENS_H_ */
-
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
new file mode 100644
index 000000000..9791d9890
--- /dev/null
+++ b/src/storage/prism/Constant.cpp
@@ -0,0 +1,43 @@
+#include "src/storage/prism/Constant.h"
+
+namespace storm {
+    namespace prism {
+        Constant::Constant(ConstantType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(true), expression(expression) {
+            // Intentionally left empty.
+        }
+        
+        Constant::Constant(ConstantType constantType, std::string const& constantName, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(false), expression() {
+            // Intentionally left empty.
+        }
+        
+        std::string const& Constant::getConstantName() const {
+            return this->constantName;
+        }
+        
+        Constant::ConstantType Constant::getConstantType() const {
+            return this->constantType;
+        }
+        
+        bool Constant::isDefined() const {
+            return this->defined;
+        }
+        
+        storm::expressions::Expression const& Constant::getExpression() const {
+            return this->expression;
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, Constant const& constant) {
+            stream << "const ";
+            switch (constant.getConstantType()) {
+                case Constant::ConstantType::Bool: stream << "bool "; break;
+                case Constant::ConstantType::Integer: stream << "int "; break;
+                case Constant::ConstantType::Double: stream << "double "; break;
+            }
+            stream << constant.getConstantName();
+            if (constant.isDefined()) {
+                stream << " = " << constant.getExpression() << ";";
+            }
+            return stream;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/prism/Constant.h b/src/storage/prism/Constant.h
new file mode 100644
index 000000000..ad1736ffd
--- /dev/null
+++ b/src/storage/prism/Constant.h
@@ -0,0 +1,91 @@
+#ifndef STORM_STORAGE_PRISM_CONSTANT_H_
+#define STORM_STORAGE_PRISM_CONSTANT_H_
+
+#include "src/storage/prism/LocatedInformation.h"
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace prism {
+        class Constant : public LocatedInformation {
+        public:
+            /*!
+             * The possible constant types.
+             */
+            enum class ConstantType {Bool, Integer, Double};
+            
+            /*!
+             * Creates a constant with the given type, name and defining expression.
+             *
+             * @param constantType The type of the constant.
+             * @param constantName The name of the constant.
+             * @param expression The expression that defines the constant.
+             * @param filename The filename in which the transition reward is defined.
+             * @param lineNumber The line number in which the transition reward is defined.
+             */
+            Constant(ConstantType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+
+            /*!
+             * Creates an undefined constant with the given type and name.
+             *
+             * @param constantType The type of the constant.
+             * @param constantName The name of the constant.
+             * @param filename The filename in which the transition reward is defined.
+             * @param lineNumber The line number in which the transition reward is defined.
+             */
+            Constant(ConstantType constantType, std::string const& constantName, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            
+            // Create default implementations of constructors/assignment.
+            Constant() = default;
+            Constant(Constant const& other) = default;
+            Constant& operator=(Constant const& other)= default;
+            Constant(Constant&& other) = default;
+            Constant& operator=(Constant&& other) = default;
+            
+            /*!
+             * Retrieves the name of the constant.
+             *
+             * @return The name of the constant.
+             */
+            std::string const& getConstantName() const;
+            
+            /*!
+             * Retrieves the type of the constant.
+             *
+             * @return The type of the constant;
+             */
+            ConstantType getConstantType() const;
+            
+            /*!
+             * Retrieves whether the constant is defined, i.e., whether there is an expression defining its value.
+             *
+             * @return True iff the constant is defined.
+             */
+            bool isDefined() const;
+            
+            /*!
+             * Retrieves the expression that defines the constant. This may only be called if the object is a defined
+             * constant.
+             *
+             * @return The expression that defines the constant.
+             */
+            storm::expressions::Expression const& getExpression() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, Constant const& constant);
+            
+        private:
+            // The type of the constant.
+            ConstantType constantType;
+            
+            // The name of the constant.
+            std::string constantName;
+            
+            // A flag that stores whether or not the constant is defined.
+            bool defined;
+            
+            // The expression that defines the constant (in case it is defined).
+            storm::expressions::Expression expression;
+        };
+    } // namespace prism
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_CONSTANT_H_ */
diff --git a/src/storage/prism/Formula.cpp b/src/storage/prism/Formula.cpp
new file mode 100644
index 000000000..e665f22f7
--- /dev/null
+++ b/src/storage/prism/Formula.cpp
@@ -0,0 +1,26 @@
+#include "src/storage/prism/Formula.h"
+
+namespace storm {
+    namespace prism {
+        Formula::Formula(std::string const& formulaName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), formulaName(formulaName), expression(expression) {
+            // Intentionally left empty.
+        }
+        
+        std::string const& Formula::getFormulaName() const {
+            return this->formulaName;
+        }
+        
+        storm::expressions::Expression const& Formula::getExpression() const {
+            return this->expression;
+        }
+        
+        storm::expressions::ExpressionReturnType Formula::getReturnType() const {
+            return this->getExpression().getReturnType();
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, Formula const& formula) {
+            stream << "formula " << formula.getFormulaName() << " = " << formula.getExpression() << ";";
+            return stream;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/prism/Formula.h b/src/storage/prism/Formula.h
new file mode 100644
index 000000000..4ae67b9dd
--- /dev/null
+++ b/src/storage/prism/Formula.h
@@ -0,0 +1,62 @@
+#ifndef STORM_STORAGE_PRISM_FORMULA_H_
+#define STORM_STORAGE_PRISM_FORMULA_H_
+
+#include "src/storage/prism/LocatedInformation.h"
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace prism {
+        class Formula : public LocatedInformation {
+        public:
+            /*!
+             * Creates a formula with the given name and expression.
+             *
+             * @param formulaName The name of the label.
+             * @param expression The predicate that needs to hold before taking a transition with the previously
+             * specified name in order to obtain the reward.
+             * @param filename The filename in which the transition reward is defined.
+             * @param lineNumber The line number in which the transition reward is defined.
+             */
+            Formula(std::string const& formulaName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            
+            // Create default implementations of constructors/assignment.
+            Formula() = default;
+            Formula(Formula const& other) = default;
+            Formula& operator=(Formula const& other)= default;
+            Formula(Formula&& other) = default;
+            Formula& operator=(Formula&& other) = default;
+            
+            /*!
+             * Retrieves the name that is associated with this formula.
+             *
+             * @return The name that is associated with this formula.
+             */
+            std::string const& getFormulaName() const;
+            
+            /*!
+             * Retrieves the expression that is associated with this formula.
+             *
+             * @return The expression that is associated with this formula.
+             */
+            storm::expressions::Expression const& getExpression() const;
+            
+            /*!
+             * Retrieves the return type of the formula, i.e., the return-type of the defining expression.
+             *
+             * @return The return type of the formula.
+             */
+            storm::expressions::ExpressionReturnType getReturnType() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, Formula const& formula);
+            
+        private:
+            // The name of the formula.
+            std::string formulaName;
+            
+            // A predicate that needs to be satisfied by states for the label to be attached.
+            storm::expressions::Expression expression;
+        };
+    } // namespace prism
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_FORMULA_H_ */
diff --git a/src/storage/prism/Label.cpp b/src/storage/prism/Label.cpp
new file mode 100644
index 000000000..297d8691e
--- /dev/null
+++ b/src/storage/prism/Label.cpp
@@ -0,0 +1,22 @@
+#include "src/storage/prism/Label.h"
+
+namespace storm {
+    namespace prism {
+        Label::Label(std::string const& labelName, storm::expressions::Expression const& statePredicateExpression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), labelName(labelName), statePredicateExpression(statePredicateExpression) {
+            // Intentionally left empty.
+        }
+
+        std::string const& Label::getLabelName() const {
+            return this->labelName;
+        }
+        
+        storm::expressions::Expression const& Label::getStatePredicateExpression() const {
+            return this->statePredicateExpression;
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, Label const& label) {
+            stream << "label \"" << label.getLabelName() << "\" = " << label.getStatePredicateExpression() << ";";
+            return stream;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/prism/Label.h b/src/storage/prism/Label.h
new file mode 100644
index 000000000..d1ae6e0fd
--- /dev/null
+++ b/src/storage/prism/Label.h
@@ -0,0 +1,55 @@
+#ifndef STORM_STORAGE_PRISM_LABEL_H_
+#define STORM_STORAGE_PRISM_LABEL_H_
+
+#include "src/storage/prism/LocatedInformation.h"
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace prism {
+        class Label : public LocatedInformation {
+        public:
+            /*!
+             * Creates a label with the given name and state predicate expression.
+             *
+             * @param labelName The name of the label.
+             * @param statePredicateExpression The predicate that needs to hold before taking a transition with the previously
+             * specified name in order to obtain the reward.
+             * @param filename The filename in which the transition reward is defined.
+             * @param lineNumber The line number in which the transition reward is defined.
+             */
+            Label(std::string const& labelName, storm::expressions::Expression const& statePredicateExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            
+            // Create default implementations of constructors/assignment.
+            Label() = default;
+            Label(Label const& other) = default;
+            Label& operator=(Label const& other)= default;
+            Label(Label&& other) = default;
+            Label& operator=(Label&& other) = default;
+            
+            /*!
+             * Retrieves the name that is associated with this label.
+             *
+             * @return The name that is associated with this label.
+             */
+            std::string const& getLabelName() const;
+            
+            /*!
+             * Retrieves the state predicate expression that is associated with this label.
+             *
+             * @return The state predicate expression that is associated with this label.
+             */
+            storm::expressions::Expression const& getStatePredicateExpression() const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, Label const& label);
+            
+        private:
+            // The name of the label.
+            std::string labelName;
+            
+            // A predicate that needs to be satisfied by states for the label to be attached.
+            storm::expressions::Expression statePredicateExpression;
+        };
+    } // namespace prism
+} // namespace storm
+
+#endif /* STORM_STORAGE_PRISM_LABEL_H_ */
diff --git a/src/storage/prism/LocatedInformation.h b/src/storage/prism/LocatedInformation.h
index f86060958..638734f9f 100644
--- a/src/storage/prism/LocatedInformation.h
+++ b/src/storage/prism/LocatedInformation.h
@@ -16,6 +16,7 @@ namespace storm {
             LocatedInformation(std::string const& filename, uint_fast64_t lineNumber);
             
             // Create default implementations of constructors/assignment.
+            LocatedInformation() = default;
             LocatedInformation(LocatedInformation const& other) = default;
             LocatedInformation& operator=(LocatedInformation const& other)= default;
             LocatedInformation(LocatedInformation&& other) = default;
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 78f561734..69abaa2b6 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -5,26 +5,29 @@
 
 namespace storm {
     namespace prism {
-        Module::Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables), commands(commands), actions(), actionsToCommandIndexMap() {
+        Module::Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), booleanVariableToIndexMap(), integerVariables(integerVariables), integerVariableToIndexMap(), commands(commands), actions(), actionsToCommandIndexMap() {
+            // FIXME: construct mappings from variable names to their indices.
             // Initialize the internal mappings for fast information retrieval.
             this->collectActions();
         }
         
         Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
             // Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception is thrown.
-            for (auto const& nameVariablePair : oldModule.getBooleanVariables()) {
-                auto renamingPair = renaming.find(nameVariablePair.first);
-                LOG_THROW(renamingPair == renaming.end(), storm::exceptions::InvalidArgumentException, "Boolean variable " << moduleName << "." << nameVariablePair.first << " was not renamed.");
-                this->booleanVariables.emplace(nameVariablePair.first, BooleanVariable(nameVariablePair.second, renamingPair->second, renaming, filename, lineNumber));
+            for (auto const& booleanVariable : oldModule.getBooleanVariables()) {
+                auto const& renamingPair = renaming.find(booleanVariable.getName());
+                LOG_THROW(renamingPair != renaming.end(), storm::exceptions::InvalidArgumentException, "Boolean variable '" << booleanVariable.getName() << " was not renamed.");
+                this->booleanVariables.emplace_back(booleanVariable, renamingPair->second, renaming, filename, lineNumber);
             }
             
             // Now do the same for the integer variables.
-            for (auto const& nameVariablePair : oldModule.getIntegerVariables()) {
-                auto renamingPair = renaming.find(nameVariablePair.first);
-                LOG_THROW(renamingPair == renaming.end(), storm::exceptions::InvalidArgumentException, "Integer variable " << moduleName << "." << nameVariablePair.first << " was not renamed.");
-                this->integerVariables.emplace(nameVariablePair.first, IntegerVariable(nameVariablePair.second, renamingPair->second, renaming, filename, lineNumber));
+            for (auto const& integerVariable : oldModule.getIntegerVariables()) {
+                auto const& renamingPair = renaming.find(integerVariable.getName());
+                LOG_THROW(renamingPair != renaming.end(), storm::exceptions::InvalidArgumentException, "Integer variable '" << integerVariable.getName() << " was not renamed.");
+                this->integerVariables.emplace_back(integerVariable, renamingPair->second, renaming, filename, lineNumber);
             }
             
+            // FIXME: construct mappings from variable names to their indices.
+            
             // Now we are ready to clone all commands and rename them if requested.
             this->commands.reserve(oldModule.getNumberOfCommands());
             for (Command const& command : oldModule.getCommands()) {
@@ -44,22 +47,22 @@ namespace storm {
         }
         
         storm::prism::BooleanVariable const& Module::getBooleanVariable(std::string const& variableName) const {
-            auto const& nameVariablePair = this->getBooleanVariables().find(variableName);
-            LOG_THROW(nameVariablePair == this->getBooleanVariables().end(), storm::exceptions::InvalidArgumentException, "Unknown boolean variable '" << variableName << "'.");
-            return nameVariablePair->second;
+            auto const& nameIndexPair = this->booleanVariableToIndexMap.find(variableName);
+            LOG_THROW(nameIndexPair != this->booleanVariableToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Unknown boolean variable '" << variableName << "'.");
+            return this->getBooleanVariables()[nameIndexPair->second];
         }
         
-        std::map<std::string, storm::prism::BooleanVariable> const& Module::getBooleanVariables() const {
+        std::vector<storm::prism::BooleanVariable> const& Module::getBooleanVariables() const {
             return this->booleanVariables;
         }
 
         storm::prism::IntegerVariable const& Module::getIntegerVariable(std::string const& variableName) const {
-            auto const& nameVariablePair = this->getIntegerVariables().find(variableName);
-            LOG_THROW(nameVariablePair == this->getIntegerVariables().end(), storm::exceptions::InvalidArgumentException, "Unknown integer variable '" << variableName << "'.");
-            return nameVariablePair->second;
+            auto const& nameIndexPair = this->integerVariableToIndexMap.find(variableName);
+            LOG_THROW(nameIndexPair != this->integerVariableToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Unknown integer variable '" << variableName << "'.");
+            return this->getIntegerVariables()[nameIndexPair->second];
         }
         
-        std::map<std::string, storm::prism::IntegerVariable> const& Module::getIntegerVariables() const {
+        std::vector<storm::prism::IntegerVariable> const& Module::getIntegerVariables() const {
             return this->integerVariables;
         }
         
@@ -67,6 +70,14 @@ namespace storm {
             return this->commands.size();
         }
         
+        std::size_t Module::getNumberOfUpdates() const {
+            std::size_t result = 0;
+            for (auto const& command : this->getCommands()) {
+                result += command.getNumberOfUpdates();
+            }
+            return result;
+        }
+        
         storm::prism::Command const& Module::getCommand(uint_fast64_t index) const {
             return this->commands[index];
         }
@@ -136,11 +147,11 @@ namespace storm {
         
         std::ostream& operator<<(std::ostream& stream, Module const& module) {
             stream << "module " << module.getName() << std::endl;
-            for (auto const& nameVariablePair : module.getBooleanVariables()) {
-                stream << "\t" << nameVariablePair.second << std::endl;
+            for (auto const& booleanVariable : module.getBooleanVariables()) {
+                stream << "\t" << booleanVariable << std::endl;
             }
-            for (auto const& nameVariablePair : module.getIntegerVariables()) {
-                stream << "\t" << nameVariablePair.second << std::endl;
+            for (auto const& integerVariable : module.getIntegerVariables()) {
+                stream << "\t" << integerVariable << std::endl;
             }
             for (auto const& command : module.getCommands()) {
                 stream << "\t" << command << std::endl;
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index d8f75d13b..cb62bc626 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -26,7 +26,7 @@ namespace storm {
              * @param filename The filename in which the module is defined.
              * @param lineNumber The line number in which the module is defined.
              */
-            Module(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Special copy constructor, implementing the module renaming functionality. This will create a new module
@@ -74,7 +74,7 @@ namespace storm {
              *
              * @return The boolean variables of the module.
              */
-            std::map<std::string, storm::prism::BooleanVariable> const& getBooleanVariables() const;
+            std::vector<storm::prism::BooleanVariable> const& getBooleanVariables() const;
             
             /*!
              * Retrieves a reference to the integer variable with the given name.
@@ -89,15 +89,22 @@ namespace storm {
              *
              * @return The integer variables of the module.
              */
-            std::map<std::string, storm::prism::IntegerVariable> const& getIntegerVariables() const;
+            std::vector<storm::prism::IntegerVariable> const& getIntegerVariables() const;
 
             /*!
              * Retrieves the number of commands of this module.
              *
-             * @return the number of commands of this module.
+             * @return The number of commands of this module.
              */
             std::size_t getNumberOfCommands() const;
             
+            /*!
+             * Retrieves the total number of updates of this module.
+             *
+             * @return The total number of updates of this module.
+             */
+            std::size_t getNumberOfUpdates() const;
+            
             /*!
              * Retrieves a reference to the command with the given index.
              *
@@ -163,11 +170,17 @@ namespace storm {
             std::string moduleName;
             
             // A list of boolean variables.
-            std::map<std::string, storm::prism::BooleanVariable> booleanVariables;
+            std::vector<storm::prism::BooleanVariable> booleanVariables;
             
-            // A list of integer variables.
-            std::map<std::string, storm::prism::IntegerVariable> integerVariables;
+            // A mapping from boolean variables to the corresponding indices in the vector.
+            std::map<std::string, uint_fast64_t> booleanVariableToIndexMap;
             
+            // A list of integer variables.
+            std::vector<storm::prism::IntegerVariable> integerVariables;
+
+            // A mapping from integer variables to the corresponding indices in the vector.
+            std::map<std::string, uint_fast64_t> integerVariableToIndexMap;
+
             // The commands associated with the module.
             std::vector<storm::prism::Command> commands;
             
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 97daf8142..281be2531 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -5,7 +5,8 @@
 
 namespace storm {
     namespace prism {
-        Program::Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> const& definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> const& definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> const& definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::map<std::string, storm::expressions::Expression>const& formulas, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), undefinedBooleanConstants(undefinedBooleanConstants), definedBooleanConstants(definedBooleanConstants), undefinedIntegerConstants(undefinedIntegerConstants), definedIntegerConstants(definedIntegerConstants), undefinedDoubleConstants(undefinedDoubleConstants), definedDoubleConstants(definedDoubleConstants), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables), formulas(formulas), modules(modules), rewardModels(rewardModels), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+        Program::Program(ModelType modelType, std::vector<Constant> const& undefinedConstants, std::vector<Constant> const& definedConstants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), undefinedConstants(undefinedConstants), definedConstants(definedConstants), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+            // FIXME: build the mappings for constants, formulas, modules, global variables, reward models and labels.
             // Now build the mapping from action names to module indices so that the lookup can later be performed quickly.
             for (unsigned int moduleIndex = 0; moduleIndex < this->getNumberOfModules(); moduleIndex++) {
                 Module const& module = this->getModule(moduleIndex);
@@ -21,10 +22,10 @@ namespace storm {
                 
                 // Put in the appropriate entries for the mapping from variable names to module index.
                 for (auto const& booleanVariable : module.getBooleanVariables()) {
-                    this->variableToModuleIndexMap[booleanVariable.first] = moduleIndex;
+                    this->variableToModuleIndexMap[booleanVariable.getName()] = moduleIndex;
                 }
                 for (auto const& integerVariable : module.getBooleanVariables()) {
-                    this->variableToModuleIndexMap[integerVariable.first] = moduleIndex;
+                    this->variableToModuleIndexMap[integerVariable.getName()] = moduleIndex;
                 }
             }
         }
@@ -34,63 +35,35 @@ namespace storm {
         }
         
         bool Program::hasUndefinedConstants() const {
-            return this->hasUndefinedBooleanConstants() || this->hasUndefinedIntegerConstants() || this->hasUndefinedDoubleConstants();
+            return this->undefinedConstants.size() > 0;
         }
         
-        bool Program::hasUndefinedBooleanConstants() const {
-            return !this->undefinedBooleanConstants.empty();
+        std::vector<Constant> const& Program::getUndefinedConstants() const {
+            return this->undefinedConstants;
         }
         
-        bool Program::hasUndefinedIntegerConstants() const {
-            return !this->undefinedIntegerConstants.empty();
-        }
-        
-        bool Program::hasUndefinedDoubleConstants() const {
-            return !this->undefinedDoubleConstants.empty();
-        }
-        
-        std::set<std::string> const& Program::getUndefinedBooleanConstants() const {
-            return this->undefinedBooleanConstants;
-        }
-        
-        std::map<std::string, storm::expressions::Expression> const& Program::getDefinedBooleanConstants() const {
-            return this->definedBooleanConstants;
-        }
-
-        std::set<std::string> const& Program::getUndefinedIntegerConstants() const {
-            return this->undefinedIntegerConstants;
-        }
-        
-        std::map<std::string, storm::expressions::Expression> const& Program::getDefinedIntegerConstants() const {
-            return this->definedIntegerConstants;
-        }
-
-        std::set<std::string> const& Program::getUndefinedDoubleConstants() const {
-            return this->undefinedDoubleConstants;
-        }
-
-        std::map<std::string, storm::expressions::Expression> const& Program::getDefinedDoubleConstants() const {
-            return this->definedDoubleConstants;
+        std::vector<Constant> const& Program::getDefinedConstants() const {
+            return this->definedConstants;
         }
 
-        std::map<std::string, storm::prism::BooleanVariable> const& Program::getGlobalBooleanVariables() const {
+        std::vector<BooleanVariable> const& Program::getGlobalBooleanVariables() const {
             return this->globalBooleanVariables;
         }
-
-        storm::prism::BooleanVariable const& Program::getGlobalBooleanVariable(std::string const& variableName) const {
-            auto const& nameVariablePair = this->getGlobalBooleanVariables().find(variableName);
-            LOG_THROW(nameVariablePair != this->getGlobalBooleanVariables().end(), storm::exceptions::OutOfRangeException, "Unknown boolean variable '" << variableName << "'.");
-            return nameVariablePair->second;
-        }
         
-        std::map<std::string, storm::prism::IntegerVariable> const& Program::getGlobalIntegerVariables() const {
+        std::vector<IntegerVariable> const& Program::getGlobalIntegerVariables() const {
             return this->globalIntegerVariables;
         }
 
-        storm::prism::IntegerVariable const& Program::getGlobalIntegerVariable(std::string const& variableName) const {
-            auto const& nameVariablePair = this->getGlobalIntegerVariables().find(variableName);
-            LOG_THROW(nameVariablePair != this->getGlobalIntegerVariables().end(), storm::exceptions::OutOfRangeException, "Unknown integer variable '" << variableName << "'.");
-            return nameVariablePair->second;
+        BooleanVariable const& Program::getGlobalBooleanVariable(std::string const& variableName) const {
+            auto const& nameIndexPair = this->globalBooleanVariableToIndexMap.find(variableName);
+            LOG_THROW(nameIndexPair != this->globalBooleanVariableToIndexMap.end(), storm::exceptions::OutOfRangeException, "Unknown boolean variable '" << variableName << "'.");
+            return this->getGlobalBooleanVariables()[nameIndexPair->second];
+        }
+
+        IntegerVariable const& Program::getGlobalIntegerVariable(std::string const& variableName) const {
+            auto const& nameIndexPair = this->globalIntegerVariableToIndexMap.find(variableName);
+            LOG_THROW(nameIndexPair != this->globalIntegerVariableToIndexMap.end(), storm::exceptions::OutOfRangeException, "Unknown integer variable '" << variableName << "'.");
+            return this->getGlobalIntegerVariables()[nameIndexPair->second];
         }
         
         std::size_t Program::getNumberOfGlobalBooleanVariables() const {
@@ -101,7 +74,7 @@ namespace storm {
             return this->getGlobalIntegerVariables().size();
         }
         
-        std::map<std::string, storm::expressions::Expression> const& Program::getFormulas() const {
+        std::vector<Formula> const& Program::getFormulas() const {
             return this->formulas;
         }
         
@@ -113,6 +86,12 @@ namespace storm {
             return this->modules[index];
         }
         
+        Module const& Program::getModule(std::string const& moduleName) const {
+            auto const& nameIndexPair = this->moduleToIndexMap.find(moduleName);
+            LOG_THROW(nameIndexPair != this->moduleToIndexMap.end(), storm::exceptions::OutOfRangeException, "Unknown module '" << moduleName << "'.");
+            return this->getModules()[nameIndexPair->second];
+        }
+        
         std::vector<storm::prism::Module> const& Program::getModules() const {
             return this->modules;
         }
@@ -131,10 +110,10 @@ namespace storm {
                 
                 for (auto const& module : this->getModules()) {
                     for (auto const& booleanVariable : module.getBooleanVariables()) {
-                        result = result && (storm::expressions::Expression::createBooleanVariable(booleanVariable.second.getName()).iff(booleanVariable.second.getInitialValueExpression()));
+                        result = result && (storm::expressions::Expression::createBooleanVariable(booleanVariable.getName()).iff(booleanVariable.getInitialValueExpression()));
                     }
                     for (auto const& integerVariable : module.getIntegerVariables()) {
-                        result = result && (storm::expressions::Expression::createIntegerVariable(integerVariable.second.getName()) == integerVariable.second.getInitialValueExpression());
+                        result = result && (storm::expressions::Expression::createIntegerVariable(integerVariable.getName()) == integerVariable.getInitialValueExpression());
                     }
                 }
                 return result;
@@ -157,17 +136,17 @@ namespace storm {
             return variableNameToModuleIndexPair->second;
         }
         
-        std::map<std::string, storm::prism::RewardModel> const& Program::getRewardModels() const {
+        std::vector<storm::prism::RewardModel> const& Program::getRewardModels() const {
             return this->rewardModels;
         }
         
         storm::prism::RewardModel const& Program::getRewardModel(std::string const& name) const {
-            auto const& nameRewardModelPair = this->getRewardModels().find(name);
-            LOG_THROW(nameRewardModelPair != this->getRewardModels().end(), storm::exceptions::OutOfRangeException, "Reward model '" << name << "' does not exist.");
-            return nameRewardModelPair->second;
+            auto const& nameIndexPair = this->rewardModelToIndexMap.find(name);
+            LOG_THROW(nameIndexPair != this->rewardModelToIndexMap.end(), storm::exceptions::OutOfRangeException, "Reward model '" << name << "' does not exist.");
+            return this->getRewardModels()[nameIndexPair->second];
         }
         
-        std::map<std::string, storm::expressions::Expression> const& Program::getLabels() const {
+        std::vector<Label> const& Program::getLabels() const {
             return this->labels;
         }
         
@@ -179,7 +158,7 @@ namespace storm {
                 newModules.push_back(module.restrictCommands(indexSet));
             }
             
-            return Program(this->getModelType(), this->getUndefinedBooleanConstants(), this->getDefinedBooleanConstants(), this->getUndefinedIntegerConstants(), this->getDefinedIntegerConstants(), this->getUndefinedDoubleConstants(), this->getDefinedDoubleConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+            return Program(this->getModelType(), this->getUndefinedConstants(), this->getDefinedConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
         }
         
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
@@ -193,22 +172,16 @@ namespace storm {
             }
             stream << std::endl;
             
-            for (auto const& element : program.getUndefinedBooleanConstants()) {
-                stream << "const bool " << element << ";" << std::endl;
-            }
-            for (auto const& element : program.getUndefinedIntegerConstants()) {
-                stream << "const int " << element << ";" << std::endl;
-            }
-            for (auto const& element : program.getUndefinedDoubleConstants()) {
-                stream << "const double " << element << ";" << std::endl;
+            for (auto const& constant : program.getUndefinedConstants()) {
+                stream << constant << std::endl;
             }
             stream << std::endl;
             
-            for (auto const& element : program.getGlobalBooleanVariables()) {
-                stream << "global " << element.second << std::endl;
+            for (auto const& variable : program.getGlobalBooleanVariables()) {
+                stream << "global " << variable << std::endl;
             }
-            for (auto const& element : program.getGlobalIntegerVariables()) {
-                stream << "global " << element.second << std::endl;
+            for (auto const& variable : program.getGlobalIntegerVariables()) {
+                stream << "global " << variable << std::endl;
             }
             stream << std::endl;
             
@@ -217,11 +190,11 @@ namespace storm {
             }
             
             for (auto const& rewardModel : program.getRewardModels()) {
-                stream << rewardModel.second << std::endl;
+                stream << rewardModel << std::endl;
             }
             
             for (auto const& label : program.getLabels()) {
-                stream << "label \"" << label.first << "\" = " << label.second <<";" << std::endl;
+                stream << label << std::endl;
             }
             
             return stream;
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 33056833a..0dbfc20fc 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -7,6 +7,9 @@
 #include <boost/container/flat_set.hpp>
 
 #include "src/storage/expressions/Expression.h"
+#include "src/storage/prism/Constant.h"
+#include "src/storage/prism/Formula.h"
+#include "src/storage/prism/Label.h"
 #include "src/storage/prism/Module.h"
 #include "src/storage/prism/RewardModel.h"
 
@@ -24,12 +27,8 @@ namespace storm {
              * models, labels and initial states.
              *
              * @param modelType The type of the program.
-             * @param undefinedBooleanConstants The undefined boolean constants of the program.
-             * @param definedBooleanConstants The defined boolean constants of the program.
-             * @param undefinedIntegerConstants The undefined integer constants of the program.
-             * @param definedIntegerConstants The defined integer constants of the program.
-             * @param undefinedDoubleConstants The undefined double constants of the program.
-             * @param definedDoubleConstants The defined double constants of the program.
+             * @param undefinedConstants The undefined constants of the program.
+             * @param definedConstants The defined integer constants of the program.
              * @param globalBooleanVariables The global boolean variables of the program.
              * @param globalIntegerVariables The global integer variables of the program.
              * @param formulas The formulas defined in the program.
@@ -44,7 +43,7 @@ namespace storm {
              * @param filename The filename in which the program is defined.
              * @param lineNumber The line number in which the program is defined.
              */
-            Program(ModelType modelType, std::set<std::string> const& undefinedBooleanConstants, std::map<std::string, storm::expressions::Expression> const& definedBooleanConstants, std::set<std::string> const& undefinedIntegerConstants, std::map<std::string, storm::expressions::Expression> const& definedIntegerConstants, std::set<std::string> const& undefinedDoubleConstants, std::map<std::string, storm::expressions::Expression> const& definedDoubleConstants, std::map<std::string, BooleanVariable> const& globalBooleanVariables, std::map<std::string, IntegerVariable> const& globalIntegerVariables, std::map<std::string, storm::expressions::Expression> const& formulas, std::vector<storm::prism::Module> const& modules, std::map<std::string, storm::prism::RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::map<std::string, storm::expressions::Expression> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Program(ModelType modelType, std::vector<Constant> const& undefinedConstants, std::vector<Constant> const& definedConstants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Provide default implementations for constructors and assignments.
             Program() = default;
@@ -68,74 +67,25 @@ namespace storm {
             bool hasUndefinedConstants() const;
             
             /*!
-             * Retrieves whether there are boolean undefined constants in the program.
+             * Retrieves the undefined constants of the program.
              *
-             * @return True iff there are boolean undefined constants in the program.
+             * @return The undefined constants of the program.
              */
-            bool hasUndefinedBooleanConstants() const;
+            std::vector<Constant> const& getUndefinedConstants() const;
 
             /*!
-             * Retrieves whether there are integer undefined constants in the program.
+             * Retrieves the defined constants of the program.
              *
-             * @return True iff there are integer undefined constants in the program.
+             * @return The defined constants of the program.
              */
-            bool hasUndefinedIntegerConstants() const;
-            
-            /*!
-             * Retrieves whether there are double undefined constants in the program.
-             *
-             * @return True iff there are double undefined constants in the program.
-             */
-            bool hasUndefinedDoubleConstants() const;
-            
-            /*!
-             * Retrieves the undefined boolean constants of the program.
-             *
-             * @return The undefined boolean constants of the program.
-             */
-            std::set<std::string> const& getUndefinedBooleanConstants() const;
-            
-            /*!
-             * Retrieves the defined boolean constants of the program.
-             *
-             * @return The defined boolean constants of the program.
-             */
-            std::map<std::string, storm::expressions::Expression> const& getDefinedBooleanConstants() const;
-            
-            /*!
-             * Retrieves the undefined integer constants of the program.
-             *
-             * @return The undefined integer constants of the program.
-             */
-            std::set<std::string> const& getUndefinedIntegerConstants() const;
-
-            /*!
-             * Retrieves the defined integer constants of the program.
-             *
-             * @return The defined integer constants of the program.
-             */
-            std::map<std::string, storm::expressions::Expression> const& getDefinedIntegerConstants() const;
-
-            /*!
-             * Retrieves the undefined double constants of the program.
-             *
-             * @return The undefined double constants of the program.
-             */
-            std::set<std::string> const& getUndefinedDoubleConstants() const;
-            
-            /*!
-             * Retrieves the defined double constants of the program.
-             *
-             * @return The defined double constants of the program.
-             */
-            std::map<std::string, storm::expressions::Expression> const& getDefinedDoubleConstants() const;
+            std::vector<Constant> const& getDefinedConstants() const;
 
             /*!
              * Retrieves the global boolean variables of the program.
              *
              * @return The global boolean variables of the program.
              */
-            std::map<std::string, storm::prism::BooleanVariable> const& getGlobalBooleanVariables() const;
+            std::vector<BooleanVariable> const& getGlobalBooleanVariables() const;
             
             /*!
              * Retrieves a the global boolean variable with the given name.
@@ -143,14 +93,14 @@ namespace storm {
              * @param variableName The name of the global boolean variable to retrieve.
              * @return The global boolean variable with the given name.
              */
-            storm::prism::BooleanVariable const& getGlobalBooleanVariable(std::string const& variableName) const;
+            BooleanVariable const& getGlobalBooleanVariable(std::string const& variableName) const;
             
             /*!
              * Retrieves the global integer variables of the program.
              *
              * @return The global integer variables of the program.
              */
-            std::map<std::string, storm::prism::IntegerVariable> const& getGlobalIntegerVariables() const;
+            std::vector<IntegerVariable> const& getGlobalIntegerVariables() const;
 
             /*!
              * Retrieves a the global integer variable with the given name.
@@ -158,7 +108,7 @@ namespace storm {
              * @param variableName The name of the global integer variable to retrieve.
              * @return The global integer variable with the given name.
              */
-            storm::prism::IntegerVariable const& getGlobalIntegerVariable(std::string const& variableName) const;
+            IntegerVariable const& getGlobalIntegerVariable(std::string const& variableName) const;
 
             /*!
              * Retrieves the number of global boolean variables of the program.
@@ -179,7 +129,7 @@ namespace storm {
              *
              * @return The formulas defined in the program.
              */
-            std::map<std::string, storm::expressions::Expression> const& getFormulas() const;
+            std::vector<Formula> const& getFormulas() const;
             
             /*!
              * Retrieves the number of modules in the program.
@@ -194,14 +144,22 @@ namespace storm {
              * @param index The index of the module to retrieve.
              * @return The module with the given index.
              */
-            storm::prism::Module const& getModule(uint_fast64_t index) const;
+            Module const& getModule(uint_fast64_t index) const;
+
+            /*!
+             * Retrieves the module with the given name.
+             *
+             * @param moduleName The name of the module to retrieve.
+             * @return The module with the given name.
+             */
+            Module const& getModule(std::string const& moduleName) const;
             
             /*!
              * Retrieves all modules of the program.
              *
              * @return All modules of the program.
              */
-            std::vector<storm::prism::Module> const& getModules() const;
+            std::vector<Module> const& getModules() const;
             
             /*!
              * Retrieves whether the program explicitly specifies an expression characterizing the initial states.
@@ -246,7 +204,7 @@ namespace storm {
              *
              * @return The reward models of the program.
              */
-            std::map<std::string, storm::prism::RewardModel> const& getRewardModels() const;
+            std::vector<RewardModel> const& getRewardModels() const;
             
             /*!
              * Retrieves the reward model with the given name.
@@ -254,14 +212,14 @@ namespace storm {
              * @param rewardModelName The name of the reward model to return.
              * @return The reward model with the given name.
              */
-            storm::prism::RewardModel const& getRewardModel(std::string const& rewardModelName) const;
+            RewardModel const& getRewardModel(std::string const& rewardModelName) const;
             
             /*!
              * Retrieves all labels that are defined by the probabilitic program.
              *
              * @return A set of labels that are defined in the program.
              */
-            std::map<std::string, storm::expressions::Expression> const& getLabels() const;
+            std::vector<Label> const& getLabels() const;
             
             /*!
              * Creates a new program that drops all commands whose indices are not in the given set.
@@ -276,38 +234,41 @@ namespace storm {
             // The type of the model.
             ModelType modelType;
             
-            // The undefined boolean constants of the program.
-            std::set<std::string> undefinedBooleanConstants;
+            // The undefined constants of the program.
+            std::vector<Constant> undefinedConstants;
             
-            // A mapping of (defined) boolean constants to their values (given as expressions).
-            std::map<std::string, storm::expressions::Expression> definedBooleanConstants;
-
-            // The undefined integer constants of the program.
-            std::set<std::string> undefinedIntegerConstants;
-
-            // A mapping of (defined) integer constants to their values (given as expressions).
-            std::map<std::string, storm::expressions::Expression> definedIntegerConstants;
-
-            // The undefined double constants of the program.
-            std::set<std::string> undefinedDoubleConstants;
-            
-            // A mapping of (defined) double constants to their values (given as expressions).
-            std::map<std::string, storm::expressions::Expression> definedDoubleConstants;
+            // The defined constants of the program.
+            std::vector<Constant> definedConstants;
 
             // The global boolean variables.
-            std::map<std::string, BooleanVariable> globalBooleanVariables;
+            std::vector<BooleanVariable> globalBooleanVariables;
+            
+            // A mapping from global boolean variable names to their corresponding indices.
+            std::map<std::string, uint_fast64_t> globalBooleanVariableToIndexMap;
             
             // The global integer variables.
-            std::map<std::string, IntegerVariable> globalIntegerVariables;
+            std::vector<IntegerVariable> globalIntegerVariables;
             
-            // A mapping of formula names to the corresponding expressions.
-            std::map<std::string, storm::expressions::Expression> formulas;
+            // A mapping from global integer variable names to their corresponding indices.
+            std::map<std::string, uint_fast64_t> globalIntegerVariableToIndexMap;
+            
+            // The formulas defined in the program.
+            std::vector<Formula> formulas;
+            
+            // A mapping of formula names to their corresponding indices.
+            std::map<std::string, uint_fast64_t> formulaToIndexMap;
             
             // The modules associated with the program.
-            std::vector<storm::prism::Module> modules;
+            std::vector<Module> modules;
+            
+            // A mapping of module names to their indices.
+            std::map<std::string, uint_fast64_t> moduleToIndexMap;
             
             // The reward models associated with the program.
-            std::map<std::string, storm::prism::RewardModel> rewardModels;
+            std::vector<RewardModel> rewardModels;
+            
+            // A mapping of reward models to their indices.
+            std::map<std::string, uint_fast64_t> rewardModelToIndexMap;
             
             // A flag that indicates whether the initial states of the program were given explicitly (in the form of an
             // initial construct) or implicitly (attached to the variable declarations).
@@ -317,7 +278,10 @@ namespace storm {
             storm::expressions::Expression initialStatesExpression;
             
             // The labels that are defined for this model.
-            std::map<std::string, storm::expressions::Expression> labels;
+            std::vector<Label> labels;
+            
+            // A mapping from label names to their corresponding indices.
+            std::map<std::string, uint_fast64_t> labelToIndexMap;
             
             // The set of actions present in this program.
             std::set<std::string> actions;
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index edd400ee2..123a16286 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -1,21 +1,23 @@
 #include "Update.h"
+#include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/OutOfRangeException.h"
 
 namespace storm {
     namespace prism {
-        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& assignments, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(likelihoodExpression), assignments(assignments), globalIndex(globalIndex) {
-            // Nothing to do here.
+        Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(likelihoodExpression), assignments(assignments), variableToAssignmentIndexMap(), globalIndex(globalIndex) {
+            // FIXME: construct the mapping from variable names to assignments and check for uniqueness.
         }
         
-        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), assignments(), globalIndex(newGlobalIndex) {
-            for (auto const& variableAssignmentPair : update.getAssignments()) {
-                auto const& namePair = renaming.find(variableAssignmentPair.first);
+        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), assignments(), variableToAssignmentIndexMap(), globalIndex(newGlobalIndex) {
+            for (auto const& assignment : update.getAssignments()) {
+                auto const& namePair = renaming.find(assignment.getVariableName());
                 if (namePair != renaming.end()) {
-                    this->assignments.emplace(namePair->second, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
+                    this->assignments.emplace_back(Assignment(assignment, renaming, filename, lineNumber));
                 } else {
-                    this->assignments.emplace(variableAssignmentPair.first, Assignment(variableAssignmentPair.second, renaming, filename, lineNumber));
+                    this->assignments.emplace_back(Assignment(assignment));
                 }
             }
+            // FIXME: construct the mapping from variable names to assignments and check for uniqueness.
             this->likelihoodExpression = update.getLikelihoodExpression().substitute<std::map>(renaming);
         }
         
@@ -27,17 +29,14 @@ namespace storm {
             return this->assignments.size();
         }
         
-        std::map<std::string, storm::prism::Assignment> const& Update::getAssignments() const {
+        std::vector<storm::prism::Assignment> const& Update::getAssignments() const {
             return this->assignments;
         }
         
         storm::prism::Assignment const& Update::getAssignment(std::string const& variableName) const {
-            auto variableAssignmentPair = this->getAssignments().find(variableName);
-            if (variableAssignmentPair == this->getAssignments().end()) {
-                throw storm::exceptions::OutOfRangeException() << "Cannot find assignment for variable '" << variableName << "' in update " << *this << ".";
-            }
-            
-            return variableAssignmentPair->second;
+            auto const& variableIndexPair = this->variableToAssignmentIndexMap.find(variableName);
+            LOG_THROW(variableIndexPair != this->variableToAssignmentIndexMap.end(), storm::exceptions::OutOfRangeException, "Variable '" << variableName << "' is not assigned in update.");
+            return this->getAssignments()[variableIndexPair->second];
         }
         
         uint_fast64_t Update::getGlobalIndex() const {
@@ -48,7 +47,7 @@ namespace storm {
             stream << update.getLikelihoodExpression() << " : ";
             uint_fast64_t i = 0;
             for (auto const& assignment : update.getAssignments()) {
-                stream << assignment.second;
+                stream << assignment;
                 if (i < update.getAssignments().size() - 1) {
                     stream << " & ";
                 }
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index 517803c2b..3a2ce087f 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -1,7 +1,7 @@
 #ifndef STORM_STORAGE_PRISM_UPDATE_H_
 #define STORM_STORAGE_PRISM_UPDATE_H_
 
-#include <map>
+#include <vector>
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/prism/Assignment.h"
@@ -11,16 +11,15 @@ namespace storm {
         class Update : public LocatedInformation {
         public:
             /*!
-             * Creates an update with the given expression specifying the likelihood and the mapping of variable to
-             * their assignments.
+             * Creates an update with the given expression specifying the likelihood and assignments.
              *
              * @param globalIndex The global index of the update.
              * @param likelihoodExpression An expression specifying the likelihood of this update.
-             * @param assignments A map of variable names to their assignments.
-             * @param filename The filename in which the variable is defined.
-             * @param lineNumber The line number in which the variable is defined.
+             * @param assignments A assignments to variables.
+             * @param filename The filename in which the update is defined.
+             * @param lineNumber The line number in which the update is defined.
              */
-            Update(uint_fast64_t index, storm::expressions::Expression const& likelihoodExpression, std::map<std::string, storm::prism::Assignment> const& assignments, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given update and performs the provided renaming.
@@ -28,8 +27,8 @@ namespace storm {
              * @param update The update that is to be copied.
              * @param newGlobalIndex The global index of the resulting update.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
-             * @param filename The filename in which the variable is defined.
-             * @param lineNumber The line number in which the variable is defined.
+             * @param filename The filename in which the update is defined.
+             * @param lineNumber The line number in which the update is defined.
              */
             Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
@@ -59,7 +58,7 @@ namespace storm {
              *
              * @return A reference to the map of variable names to their respective assignments.
              */
-            std::map<std::string, storm::prism::Assignment> const& getAssignments() const;
+            std::vector<storm::prism::Assignment> const& getAssignments() const;
             
             /*!
              * Retrieves a reference to the assignment for the variable with the given name.
@@ -81,8 +80,11 @@ namespace storm {
             // An expression specifying the likelihood of taking this update.
             storm::expressions::Expression likelihoodExpression;
             
-            // A mapping of variable names to their assignments in this update.
-            std::map<std::string, storm::prism::Assignment> assignments;
+            // The assignments of this update.
+            std::vector<storm::prism::Assignment> assignments;
+            
+            // A mapping from variable names to their assignments.
+            std::map<std::string, uint_fast64_t> variableToAssignmentIndexMap;
             
             // The global index of the update.
             uint_fast64_t globalIndex;
diff --git a/src/storm.cpp b/src/storm.cpp
index a13bf8e23..16fa59806 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -54,6 +54,7 @@
 #include "log4cplus/loggingmacros.h"
 #include "log4cplus/consoleappender.h"
 #include "log4cplus/fileappender.h"
+log4cplus::Logger logger;
 
 #include "src/parser/PrismParser.h"
 #include "src/adapters/ExplicitModelAdapter.h"
@@ -121,8 +122,6 @@ void printUsage() {
 #endif
 }
 
-log4cplus::Logger logger;
-
 /*!
  * Initializes the logging framework and sets up logging to console.
  */

From f6587b424d2c3b67447526220e0d1cd3918910d1 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 11 Apr 2014 23:08:04 +0200
Subject: [PATCH 069/147] Further work on PrismParser and the related PRISM
 classes...

Former-commit-id: be4ae055ddb1d042a25f6f0ad952fa1878dcf0b8
---
 src/parser/PrismParser.cpp                    |  98 -----
 src/parser/PrismParser.h                      |  35 --
 src/parser/prismparser/PrismGrammar.cpp       | 415 +++++++++++++-----
 src/parser/prismparser/PrismGrammar.h         | 230 ++++++----
 src/parser/prismparser/PrismParser.cpp        |  70 +++
 src/parser/prismparser/PrismParser.h          |  36 ++
 .../BinaryBooleanFunctionExpression.cpp       |   4 +-
 src/storage/expressions/Expression.cpp        |   4 +
 src/storage/expressions/Expression.h          |   1 +
 src/storage/prism/BooleanVariable.h           |   4 +-
 src/storage/prism/Command.cpp                 |   8 +-
 src/storage/prism/Command.h                   |   3 +-
 src/storage/prism/Constant.cpp                |   3 +-
 src/storage/prism/IntegerVariable.cpp         |   2 +-
 src/storage/prism/LocatedInformation.cpp      |   8 +
 src/storage/prism/LocatedInformation.h        |  14 +
 src/storage/prism/Module.cpp                  |  37 +-
 src/storage/prism/Module.h                    |   6 +-
 src/storage/prism/Program.cpp                 | 106 +++--
 src/storage/prism/Program.h                   |  49 ++-
 src/storage/prism/Update.cpp                  |  15 +-
 src/storage/prism/Update.h                    |   5 +
 test/functional/parser/PrismParserTest.cpp    | 157 +++++++
 23 files changed, 925 insertions(+), 385 deletions(-)
 delete mode 100644 src/parser/PrismParser.cpp
 delete mode 100644 src/parser/PrismParser.h
 create mode 100644 src/parser/prismparser/PrismParser.cpp
 create mode 100644 src/parser/prismparser/PrismParser.h
 create mode 100644 test/functional/parser/PrismParserTest.cpp

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
deleted file mode 100644
index 98f58f208..000000000
--- a/src/parser/PrismParser.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "src/parser/PrismParser.h"
-
-#include "src/parser/prismparser/PrismGrammar.h"
-
-// If the parser fails due to ill-formed data, this exception is thrown.
-#include "src/exceptions/WrongFormatException.h"
-
-// Needed for file IO.
-#include <fstream>
-#include <iomanip>
-#include <limits>
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-#include "log4cplus/consoleappender.h"
-#include "log4cplus/fileappender.h"
-log4cplus::Logger logger;
-
-namespace storm {
-    namespace parser {
-        storm::prism::Program PrismParserFromFile(std::string const& filename) {
-            // Open file and initialize result.
-            std::ifstream inputFileStream(filename, std::ios::in);
-            storm::prism::Program result;
-            
-            // Now try to parse the contents of the file.
-            try {
-                result = PrismParser(inputFileStream, filename);
-            } catch(std::exception& e) {
-                // In case of an exception properly close the file before passing exception.
-                inputFileStream.close();
-                throw e;
-            }
-            
-            // Close the stream in case everything went smoothly and return result.
-            inputFileStream.close();
-            return result;
-        }
-        
-        storm::prism::Program PrismParser(std::istream& inputStream, std::string const& filename) {
-            // Prepare iterators to input.
-            // TODO: Right now, this parses the whole contents of the file into a string first.
-            // While this is usually not necessary, because there exist adapters that make an input stream
-            // iterable in both directions without storing it into a string, using the corresponding
-            // Boost classes gives an awful output under valgrind and is thus disabled for the time being.
-            std::string fileContent((std::istreambuf_iterator<char>(inputStream)), (std::istreambuf_iterator<char>()));
-            BaseIteratorType stringIteratorBegin = fileContent.begin();
-            BaseIteratorType stringIteratorEnd = fileContent.end();
-            PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename);
-            PositionIteratorType positionIteratorBegin2(stringIteratorBegin, stringIteratorEnd, filename);
-            PositionIteratorType positionIteratorEnd;
-            
-            // Prepare resulting intermediate representation of input.
-            storm::prism::Program result;
-            
-            // In order to instantiate the grammar, we have to pass the type of the skipping parser.
-            // As this is more complex, we let Boost figure out the actual type for us.
-            storm::parser::prism::PrismGrammar grammar;
-            try {
-                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
-                // First run.
-                LOG4CPLUS_INFO(logger, "Start parsing...");
-                qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
-                LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result);
-
-            } catch(const qi::expectation_failure<PositionIteratorType>& e) {
-                // If the parser expected content different than the one provided, display information
-                // about the location of the error.
-                const boost::spirit::classic::file_position_base<std::string>& pos = e.first.get_position();
-                
-                // Construct the error message including a caret display of the position in the
-                // erroneous line.
-                std::stringstream msg;
-                std::string line = e.first.get_currentline();
-                while (line.find('\t') != std::string::npos) line.replace(line.find('\t'),1," ");
-                msg << pos.file << ", line " << pos.line << ", column " << pos.column
-				<< ": parse error: expected " << e.what_ << std::endl << "\t"
-				<< line << std::endl << "\t";
-                int i = 0;
-                for (i = 1; i < pos.column; ++i) {
-                    msg << "-";
-                }
-                msg << "^";
-                for (; i < 80; ++i) {
-                    msg << "-";
-                }
-                msg << std::endl;
-                
-                std::cerr << msg.str();
-                
-                // Now propagate exception.
-                throw storm::exceptions::WrongFormatException() << msg.str();
-            }
-            
-            return result;
-        }
-    } // namespace parser
-} // namespace storm
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
deleted file mode 100644
index 49bdd20c5..000000000
--- a/src/parser/PrismParser.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef STORM_PARSER_PRISMPARSER_H_
-#define STORM_PARSER_PRISMPARSER_H_
-
-// All classes of the intermediate representation are used.
-#include "src/storage/prism/Program.h"
-
-// Used for file input.
-#include <istream>
-
-namespace storm {
-    namespace parser {
-        using namespace storm::prism;
-        using namespace storm::expressions;
-        
-        /*!
-         * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
-         *
-         * @param filename the name of the file to parse.
-         * @return The resulting PRISM program.
-         */
-        storm::prism::Program PrismParserFromFile(std::string const& filename);
-        
-        /*!
-         * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
-         *
-         * @param inputStream The input stream to parse.
-         * @param filename The name of the file the input stream belongs to.
-         * @return The resulting PRISM program.
-         */
-        storm::prism::Program PrismParser(std::istream& inputStream, std::string const& filename);
-        
-    } // namespace parser
-} // namespace storm
-
-#endif /* STORM_PARSER_PRISMPARSER_H_ */
diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp
index 72b7a40b8..b8c06daa9 100644
--- a/src/parser/prismparser/PrismGrammar.cpp
+++ b/src/parser/prismparser/PrismGrammar.cpp
@@ -1,153 +1,372 @@
+// #define BOOST_SPIRIT_DEBUG
 #include "src/parser/prismparser/PrismGrammar.h"
 #include "src/exceptions/InvalidArgumentException.h"
+#include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
     namespace parser {
         namespace prism {
-            PrismGrammar::PrismGrammar() : PrismGrammar::base_type(start) {
+            PrismGrammar::PrismGrammar(std::string const& filename, Iterator first) : PrismGrammar::base_type(start), doExpressionGeneration(false), filename(filename), annotate(first) {
                 // Parse simple identifier.
-                identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]] - keywords_;
+                identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&PrismGrammar::isValidIdentifier, phoenix::ref(*this), qi::_1)];
                 identifier.name("identifier");
                 
-                // Parse a composed expression.
-                expression %= (booleanExpression | numericalExpression);
-                expression.name("expression");
+                setExpressionGeneration(doExpressionGeneration);
                 
-                booleanExpression %= orExpression;
-                expression.name("boolean expression");
-                
-                orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = qi::_val * qi::_1];
-                orExpression.name("boolean expression");
-                
-                andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = qi::_val * qi::_1];
-                andExpression.name("boolean expression");
-                
-                notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = !qi::_1];
-                notExpression.name("boolean expression");
-                
-                atomicBooleanExpression %= relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")");
-                atomicBooleanExpression.name("boolean expression");
-                
-                relativeExpression = ((numericalExpression >> ">") > numericalExpression)[qi::_val = qi::_1 > qi::_2] | ((numericalExpression >> ">=") > numericalExpression)[qi::_val = qi::_1 >= qi::_2] | ((numericalExpression >> "<") > numericalExpression)[qi::_val = qi::_1 < qi::_2] | ((numericalExpression >> "<=") > numericalExpression)[qi::_val = qi::_1 <= qi::_2];
-                relativeExpression.name("relative expression");
-                
-                booleanVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createBooleanVariable, qi::_1)];
-                booleanVariableExpression.name("boolean variable");
-                
-                numericalExpression %= plusExpression;
-                numericalExpression.name("numerical expression");
-                
-                plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = qi::_val + qi::_1] .else_ [qi::_val = qi::_val - qi::_1]];
-                plusExpression.name("numerical expression");
-                
-                multiplicationExpression = atomicNumericalExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicNumericalExpression[qi::_val = qi::_val * qi::_1]);
-                multiplicationExpression.name("numerical expression");
-                
-                atomicNumericalExpression %= minMaxExpression | floorCeilExpression | numericalVariableExpression | qi::lit("(") >> numericalExpression >> qi::lit(")");
-                atomicNumericalExpression.name("numerical expression");
-                
-                minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(",") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]];
-                minMaxExpression.name("min/max expression");
-                
-                floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]];
-                floorCeilExpression.name("integer floor/ceil expression");
-
-                numericalVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleVariable, qi::_1)];
-                numericalVariableExpression.name("numerical variable");
-                
-                modelTypeDefinition = modelType_;
+                modelTypeDefinition %= modelType_;
                 modelTypeDefinition.name("model type");
-                
-                undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r1) | undefinedDoubleConstantDefinition(qi::_r1));
-                undefinedConstantDefinition.name("undefined constant definition");
 
-                undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, phoenix::bind(&GlobalProgramInformation::undefinedBooleanConstants, qi::_r1), qi::_1)];
+                undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedBooleanConstant, phoenix::ref(*this), qi::_1)];
                 undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
 
-                undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, phoenix::bind(&GlobalProgramInformation::undefinedIntegerConstants, qi::_r1), qi::_1)];
+                undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedIntegerConstant, phoenix::ref(*this), qi::_1)];
                 undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
                 
-                undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, phoenix::bind(&GlobalProgramInformation::undefinedDoubleConstants, qi::_r1), qi::_1)];
+                undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedDoubleConstant, phoenix::ref(*this), qi::_1)];
                 undefinedDoubleConstantDefinition.name("undefined double constant definition");
 
-                definedConstantDefinition %= (definedBooleanConstantDefinition(qi::_r1) | definedIntegerConstantDefinition(qi::_r1) | definedDoubleConstantDefinition(qi::_r1));
-                definedConstantDefinition.name("defined constant definition");
+                undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition);
+                undefinedConstantDefinition.name("undefined constant definition");
 
-                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedBooleanConstant, phoenix::bind(&GlobalProgramInformation::definedBooleanConstants, qi::_r1), qi::_1, qi::_2)];
+                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)];
                 definedBooleanConstantDefinition.name("defined boolean constant declaration");
 
-                definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedIntegerConstant, phoenix::bind(&GlobalProgramInformation::definedIntegerConstants, qi::_r1), qi::_1, qi::_2)];
+                definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)];
                 definedIntegerConstantDefinition.name("defined integer constant declaration");
 
-                definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedDoubleConstant, phoenix::bind(&GlobalProgramInformation::definedDoubleConstants, qi::_r1), qi::_1, qi::_2)];
+                definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)];
                 definedDoubleConstantDefinition.name("defined double constant declaration");
                 
-                formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addFormula, phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1, qi::_2)];
+                definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
+                definedConstantDefinition.name("defined constant definition");
+                
+                formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createFormula, phoenix::ref(*this), qi::_1, qi::_2)];
                 formulaDefinition.name("formula definition");
                 
-                globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1)) | integerVariableDefinition(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1))));
+                booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)];
+                booleanVariableDefinition.name("boolean variable definition");
+                
+                integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismGrammar::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression[qi::_a = qi::_1] > qi::lit("..") > expression > qi::lit("]")[phoenix::bind(&PrismGrammar::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)];
+                integerVariableDefinition.name("integer variable definition");
+                
+                variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]);
+                variableDefinition.name("variable declaration");
+                
+                globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)]));
                 globalVariableDefinition.name("global variable declaration list");
                 
-                programHeader =         modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
-                                >   *(  undefinedConstantDefinition(qi::_r1)
-                                    |   definedConstantDefinition(qi::_r1)
-                                    |   formulaDefinition(qi::_r1)
-                                    |   globalVariableDefinition(qi::_r1)
-                                    );
+                programHeader = modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
+                                    >   *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)] | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)])
+                                    >   *(formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1)])
+                                    >   *(globalVariableDefinition(qi::_r1));
                 programHeader.name("program header");
- 
-                rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"")
-                                         > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)]
-                                            |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
-                                            )
-                                         >> qi::lit("endrewards"))[phoenix::bind(&PrismGrammar::addRewardModel, phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_r1), qi::_1, qi::_a, qi::_b)];
-                rewardModelDefinition.name("reward model definition");
                 
-                stateRewardDefinition = (booleanExpression > qi::lit(":") > numericalExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createStateReward, qi::_1, qi::_2)];
+                stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
                 stateRewardDefinition.name("state reward definition");
                 
-                transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > numericalExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createTransitionReward, qi::_a, qi::_2, qi::_3)];
+                transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
                 transitionRewardDefinition.name("transition reward definition");
 
-                labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > booleanExpression >> qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addLabel, phoenix::bind(&GlobalProgramInformation::labels, qi::_r1), qi::_1, qi::_2)];
+                rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"")
+                                         > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)]
+                                             |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
+                                             )
+                                         >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismGrammar::createRewardModel, phoenix::ref(*this), qi::_1, qi::_a, qi::_b)];
+                rewardModelDefinition.name("reward model definition");
+                
+                initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismGrammar::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)];
+                initialStatesConstruct.name("initial construct");
+                
+                labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
                 labelDefinition.name("label definition");
 
-                assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_pass = phoenix::bind(&PrismGrammar::addAssignment, qi::_r1, qi::_1, qi::_2)];
+                assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&PrismGrammar::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)];
                 assignmentDefinition.name("assignment");
-                assignmentDefinitionList = assignmentDefinition(qi::_r1) % "&";
-                assignmentDefinitionList.name("assignment list");
                 
-                moduleDefinitionList %= +(moduleDefinition(qi::_r1) | moduleRenaming(qi::_r1));
-                moduleDefinitionList.name("module list");
+                assignmentDefinitionList %= +assignmentDefinition % "&";
+                assignmentDefinitionList.name("assignment list");
 
-                updateDefinition = (((numericalExpression >> qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList(qi::_a))[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, qi::_1, qi::_a)];
+                updateDefinition = (((plusExpression > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)];
                 updateDefinition.name("update");
                 
-                updateListDefinition %= +updateDefinition % "+";
+                updateListDefinition %= +updateDefinition(qi::_r1) % "+";
                 updateListDefinition.name("update list");
                 
-                commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createCommand, qi::_a, qi::_2, qi::_3)];
+                commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)];
                 commandDefinition.name("command definition");
 
-                booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > booleanExpression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addBooleanVariable, qi::_r1, qi::_1, qi::_2)];
-                booleanVariableDefinition.name("boolean variable definition");
-                
-                integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")) > numericalExpression[qi::_a = qi::_1] > qi::lit("..") > numericalExpression > qi::lit("]") > -(qi::lit("init") > numericalExpression[qi::_a = qi::_1]) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addIntegerVariable, qi::_r1, qi::_1, qi::_2, qi::_3, qi::_a)];
-                integerVariableDefinition.name("integer variable definition");
-                
-                variableDefinition = (booleanVariableDefinition(qi::_r1) | integerVariableDefinition(qi::_r2));
-                variableDefinition.name("variable declaration");
-
-                moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createModule, qi::_1, qi::_a, qi::_b, qi::_2)];
+                moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition(qi::_r1) > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createModule, phoenix::ref(*this), qi::_1, qi::_a, qi::_b, qi::_2, qi::_r1)];
                 moduleDefinition.name("module definition");
                 
-                moduleRenaming = ((qi::lit("module")	>> identifier >> qi::lit("=")) > identifier > qi::lit("[")
+                moduleRenaming = ((qi::lit("module") >> identifier >> qi::lit("=")) > identifier > qi::lit("[")
                                   > ((identifier > qi::lit("=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))] % ",") > qi::lit("]")
-                                  > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createRenamedModule, qi::_1, qi::_2, qi::_a, qi::_r1)];
+                                  > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createRenamedModule, phoenix::ref(*this), qi::_1, qi::_2, qi::_a, qi::_r1)];
                 moduleRenaming.name("module definition via renaming");
                 
-                start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(rewardModelDefinition(qi::_a) | labelDefinition(qi::_a)))[qi::_val = phoenix::bind(&PrismGrammar::createProgram, qi::_a, qi::_1)];
+                moduleDefinitionList %= +(moduleRenaming(qi::_r1) | moduleDefinition(qi::_r1))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_r1), qi::_1)];
+                moduleDefinitionList.name("module list");
+
+                start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(initialStatesConstruct(qi::_a) | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)]) > qi::eoi)[qi::_val = phoenix::bind(&PrismGrammar::createProgram, phoenix::ref(*this), qi::_a)];
                 start.name("probabilistic program");
+
+                // Enable location tracking for important entities.
+                auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
+                qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction);
+                qi::on_success(undefinedIntegerConstantDefinition, setLocationInfoFunction);
+                qi::on_success(undefinedDoubleConstantDefinition, setLocationInfoFunction);
+                qi::on_success(definedBooleanConstantDefinition, setLocationInfoFunction);
+                qi::on_success(definedIntegerConstantDefinition, setLocationInfoFunction);
+                qi::on_success(definedDoubleConstantDefinition, setLocationInfoFunction);
+                qi::on_success(booleanVariableDefinition, setLocationInfoFunction);
+                qi::on_success(integerVariableDefinition, setLocationInfoFunction);
+                qi::on_success(moduleDefinition, setLocationInfoFunction);
+                qi::on_success(moduleRenaming, setLocationInfoFunction);
+                qi::on_success(formulaDefinition, setLocationInfoFunction);
+                qi::on_success(rewardModelDefinition, setLocationInfoFunction);
+                qi::on_success(labelDefinition, setLocationInfoFunction);
+                qi::on_success(commandDefinition, setLocationInfoFunction);
+                qi::on_success(updateDefinition, setLocationInfoFunction);
+                qi::on_success(assignmentDefinition, setLocationInfoFunction);
+            }
+            
+            void PrismGrammar::setExpressionGeneration(bool doExpressionGeneration) {
+                if (doExpressionGeneration) {
+                    floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]];
+                    floorCeilExpression.name("floor/ceil expression");
+                    
+                    minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]];
+                    minMaxExpression.name("min/max expression");
+                    
+                    identifierExpression = identifier[qi::_val = phoenix::bind(&PrismGrammar::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
+                    identifierExpression.name("identifier expression");
+                    
+                    literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | strict_double[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleLiteral, qi::_1)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)];
+                    literalExpression.name("literal expression");
+                    
+                    atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression;
+                    atomicExpression.name("atomic expression");
+                    
+                    unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = !qi::_1] | (qi::lit("-") >> atomicExpression)[qi::_val = -qi::_1];
+                    unaryExpression.name("unary expression");
+                    
+                    multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = qi::_val * qi::_1] .else_ [qi::_val = qi::_val / qi::_1]]);
+                    multiplicationExpression.name("multiplication expression");
+                    
+                    plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = qi::_val + qi::_1] .else_ [qi::_val = qi::_val - qi::_1]];
+                    plusExpression.name("plus expression");
+                    
+                    relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = qi::_1 >= qi::_1] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = qi::_1 > qi::_2] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = qi::_1 <= qi::_2] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = qi::_1 < qi::_2] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = qi::_1 == qi::_2] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = qi::_1 != qi::_2] | plusExpression[qi::_val = qi::_1];
+                    relativeExpression.name("relative expression");
+                    
+                    andExpression = relativeExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> relativeExpression)[qi::_val = qi::_val && qi::_1];
+                    andExpression.name("and expression");
+                    
+                    orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = qi::_val || qi::_1];
+                    orExpression.name("or expression");
+                    
+                    expression %= orExpression;
+                    expression.name("expression");
+                } else {
+                    floorCeilExpression = ((qi::lit("floor") | qi::lit("ceil")) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    floorCeilExpression.name("floor/ceil expression");
+                    
+                    minMaxExpression = ((qi::lit("min") | qi::lit("max")) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    minMaxExpression.name("min/max expression");
+                    
+                    identifierExpression = identifier[qi::_val = phoenix::construct<storm::expressions::Expression>(), qi::_pass = phoenix::bind(&PrismGrammar::isValidIdentifier, phoenix::ref(*this), qi::_1)];
+                    identifierExpression.name("identifier expression");
+                    
+                    literalExpression = (qi::lit("true") | qi::lit("false") | strict_double | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    literalExpression.name("literal expression");
+                    
+                    atomicExpression = (minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    atomicExpression.name("atomic expression");
+                    
+                    unaryExpression = (atomicExpression | (qi::lit("!") >> atomicExpression) | (qi::lit("-") >> atomicExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    unaryExpression.name("unary expression");
+                    
+                    multiplicationExpression = (unaryExpression >> *((qi::lit("*") | qi::lit("/")) >> unaryExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    multiplicationExpression.name("multiplication expression");
+                    
+                    plusExpression = (multiplicationExpression >> *((qi::lit("+") | qi::lit("-")) >> multiplicationExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    plusExpression.name("plus expression");
+                    
+                    relativeExpression = ((plusExpression >> qi::lit(">=") >> plusExpression) | (plusExpression >> qi::lit(">") >> plusExpression) | (plusExpression >> qi::lit("<=") >> plusExpression) | (plusExpression >> qi::lit("<") >> plusExpression) | (plusExpression >> qi::lit("=") >> plusExpression) | (plusExpression >> qi::lit("!=") >> plusExpression) | plusExpression)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    relativeExpression.name("relative expression");
+                    
+                    andExpression = (relativeExpression >> *(qi::lit("&") >> relativeExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    andExpression.name("and expression");
+                    
+                    orExpression = (andExpression >> *(qi::lit("|") >> andExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                    orExpression.name("or expression");
+                    
+                    expression %= orExpression;
+                    expression.name("expression");
+                }
+                
+                // Enable error reporting.
+                qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+                
+                // Finally toggle the internal flag.
+                this->doExpressionGeneration = doExpressionGeneration;
+            }
+            
+            void PrismGrammar::toggleExpressionGeneration() {
+                setExpressionGeneration(!doExpressionGeneration);
+            }
+            
+            void PrismGrammar::allowDoubleLiterals(bool flag) {
+                if (flag) {
+                    if (this->doExpressionGeneration) {
+                        literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | strict_double[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleLiteral, qi::_1)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)];
+                        literalExpression.name("literal expression");
+                    } else {
+                        literalExpression = (qi::lit("true") | qi::lit("false") | strict_double | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                        literalExpression.name("literal expression");
+                    }
+                } else {
+                    if (this->doExpressionGeneration) {
+                        literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)];
+                        literalExpression.name("literal expression");
+                    } else {
+                        literalExpression = (qi::lit("true") | qi::lit("false") | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
+                        literalExpression.name("literal expression");
+                    }
+                }
+            }
+            
+            std::string const& PrismGrammar::getFilename() const {
+                return this->filename;
+            }
+            
+            bool PrismGrammar::isValidIdentifier(std::string const& identifier) {
+                if (this->keywords_.find(identifier) != nullptr) {
+                    return false;
+                }
+                return true;
+            }
+            
+            bool PrismGrammar::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
+                LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::InvalidArgumentException, "Program must not define two initial constructs.");
+                if (globalProgramInformation.hasInitialStatesExpression) {
+                    return false;
+                }
+                globalProgramInformation.hasInitialStatesExpression = true;
+                globalProgramInformation.initialStatesExpression = initialStatesExpression;
+                return true;
+            }
+            
+            storm::expressions::Expression PrismGrammar::getIdentifierExpression(std::string const& identifier) const {
+                storm::expressions::Expression const* expression = this->identifiers_.find(identifier);
+                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Undeclared identifier '" << identifier << "'.");
+                return *expression;
+            }
+            
+            storm::prism::Constant PrismGrammar::createUndefinedBooleanConstant(std::string const& newConstant) const {
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+                return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, this->getFilename());
+            }
+            
+            storm::prism::Constant PrismGrammar::createUndefinedIntegerConstant(std::string const& newConstant) const {
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+                return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, this->getFilename());
+            }
+            
+            storm::prism::Constant PrismGrammar::createUndefinedDoubleConstant(std::string const& newConstant) const {
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+                return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, this->getFilename());
+            }
+            
+            storm::prism::Constant PrismGrammar::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+                return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, expression, this->getFilename());
+            }
+            
+            storm::prism::Constant PrismGrammar::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+                return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, expression, this->getFilename());
+            }
+            
+            storm::prism::Constant PrismGrammar::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+                return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, expression, this->getFilename());
+            }
+            
+            storm::prism::Formula PrismGrammar::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
+                this->identifiers_.add(formulaName, expression);
+                return storm::prism::Formula(formulaName, expression, this->getFilename());
+            }
+            
+            storm::prism::Label PrismGrammar::createLabel(std::string const& labelName, storm::expressions::Expression expression) const {
+                return storm::prism::Label(labelName, expression, this->getFilename());
+            }
+            
+            storm::prism::RewardModel PrismGrammar::createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const {
+                return storm::prism::RewardModel(rewardModelName, stateRewards, transitionRewards, this->getFilename());
+            }
+            
+            storm::prism::StateReward PrismGrammar::createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
+                return storm::prism::StateReward(statePredicateExpression, rewardValueExpression, this->getFilename());
+            }
+            
+            storm::prism::TransitionReward PrismGrammar::createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
+                return storm::prism::TransitionReward(actionName, statePredicateExpression, rewardValueExpression, this->getFilename());
+            }
+            
+            storm::prism::Assignment PrismGrammar::createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const {
+                return storm::prism::Assignment(variableName, assignedExpression, this->getFilename());
+            }
+            
+            storm::prism::Update PrismGrammar::createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const {
+                ++globalProgramInformation.currentUpdateIndex;
+                return storm::prism::Update(globalProgramInformation.currentUpdateIndex - 1, likelihoodExpression, assignments, this->getFilename());
+            }
+            
+            storm::prism::Command PrismGrammar::createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const {
+                ++globalProgramInformation.currentCommandIndex;
+                return storm::prism::Command(globalProgramInformation.currentCommandIndex - 1, actionName, guardExpression, updates, this->getFilename());
+            }
+            
+            storm::prism::BooleanVariable PrismGrammar::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const {
+                this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
+                return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename());
+            }
+            
+            storm::prism::IntegerVariable PrismGrammar::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const {
+                this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
+                return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename());
+            }
+            
+            storm::prism::Module PrismGrammar::createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const {
+                globalProgramInformation.moduleToIndexMap[moduleName] = globalProgramInformation.modules.size();
+                return storm::prism::Module(moduleName, booleanVariables, integerVariables, commands, this->getFilename());
+            }
+            
+            storm::prism::Module PrismGrammar::createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const {
+                auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
+                LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "No module named '" << oldModuleName << "' to rename.");
+                globalProgramInformation.moduleToIndexMap[newModuleName] = globalProgramInformation.modules.size();
+                uint_fast64_t commandBaseIndex = globalProgramInformation.currentCommandIndex;
+                uint_fast64_t updateBaseIndex = globalProgramInformation.currentUpdateIndex;
+                storm::prism::Module const& moduleToClone = globalProgramInformation.modules[moduleIndexPair->second];
+                globalProgramInformation.currentCommandIndex += moduleToClone.getNumberOfCommands();
+                globalProgramInformation.currentUpdateIndex += moduleToClone.getNumberOfUpdates();
+                return storm::prism::Module(moduleToClone, newModuleName, commandBaseIndex, updateBaseIndex, renaming, this->getFilename());
+            }
+            
+            storm::prism::Program PrismGrammar::createProgram(GlobalProgramInformation const& globalProgramInformation) const {
+                return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, globalProgramInformation.hasInitialStatesExpression, globalProgramInformation.initialStatesExpression, globalProgramInformation.labels, this->getFilename());
             }
         } // namespace prism
     } // namespace parser
diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h
index d51ee4f04..29d0afb96 100644
--- a/src/parser/prismparser/PrismGrammar.h
+++ b/src/parser/prismparser/PrismGrammar.h
@@ -4,33 +4,32 @@
 // Include files for file input.
 #include <istream>
 #include <memory>
+#include <iomanip>
 
 // Include boost spirit.
+#define BOOST_SPIRIT_USE_PHOENIX_V3
 #include <boost/typeof/typeof.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix.hpp>
-
-// Include headers for spirit iterators. Needed for diagnostics and input stream iteration.
-#include <boost/spirit/include/classic_position_iterator.hpp>
-#include <boost/spirit/include/support_multi_pass.hpp>
+#include <boost/spirit/include/support_line_pos_iterator.hpp>
+#include <boost/spirit/home/classic/iterator/position_iterator.hpp>
 
 namespace qi = boost::spirit::qi;
 namespace phoenix = boost::phoenix;
 
 typedef std::string::const_iterator BaseIteratorType;
-typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
+typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType;
 typedef PositionIteratorType Iterator;
 typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
 typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
-typedef boost::spirit::unused_type Unused;
 
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
     namespace parser {
         namespace prism {
-            
             struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
                 modelTypeStruct() {
                     add
@@ -42,7 +41,7 @@ namespace storm {
                 }
             };
             
-            struct keywordsStruct : qi::symbols<char, unsigned> {
+            struct keywordsStruct : qi::symbols<char, bool> {
                 keywordsStruct() {
                     add
                     ("dtmc", 1)
@@ -58,7 +57,12 @@ namespace storm {
                     ("rewards", 11)
                     ("endrewards", 12)
                     ("true", 13)
-                    ("false", 14);
+                    ("min", 14)
+                    ("max", 15)
+                    ("floor", 16)
+                    ("ceil", 17)
+                    ("init", 18)
+                    ("endinit", 19);
                 }
             };
             
@@ -69,32 +73,104 @@ namespace storm {
                 
                 // Members for all essential information that needs to be collected.
                 storm::prism::Program::ModelType modelType;
-                std::set<std::string> undefinedBooleanConstants;
-                std::set<std::string> undefinedIntegerConstants;
-                std::set<std::string> undefinedDoubleConstants;
-                std::map<std::string, storm::expressions::Expression> definedBooleanConstants;
-                std::map<std::string, storm::expressions::Expression> definedIntegerConstants;
-                std::map<std::string, storm::expressions::Expression> definedDoubleConstants;
-                std::map<std::string, storm::expressions::Expression> formulas;
-                std::map<std::string, storm::prism::BooleanVariable> globalBooleanVariables;
-                std::map<std::string, storm::prism::IntegerVariable> globalIntegerVariables;
-                std::map<std::string, storm::prism::Module> modules;
-                std::map<std::string, storm::prism::RewardModel> rewardModels;
-                std::map<std::string, storm::expressions::Expression> labels;
+                std::vector<storm::prism::Constant> constants;
+                std::vector<storm::prism::Formula> formulas;
+                std::vector<storm::prism::BooleanVariable> globalBooleanVariables;
+                std::vector<storm::prism::IntegerVariable> globalIntegerVariables;
+                std::map<std::string, uint_fast64_t> moduleToIndexMap;
+                std::vector<storm::prism::Module> modules;
+                std::vector<storm::prism::RewardModel> rewardModels;
+                std::vector<storm::prism::Label> labels;
+                storm::expressions::Expression initialStatesExpression;
+                bool hasInitialStatesExpression;
                 
                 // Counters to provide unique indexing for commands and updates.
                 uint_fast64_t currentCommandIndex;
                 uint_fast64_t currentUpdateIndex;
             };
             
+            // Functor used for displaying error information.
+            struct ErrorHandler {
+                typedef qi::error_handler_result result_type;
+                
+                template<typename T1, typename T2, typename T3, typename T4>
+                qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
+//                    LOG4CPLUS_ERROR(logger, "Error: expecting " << what << " in line " << get_line(where) << " at column " << get_column(b, where, 4) << ".");
+                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << "." << std::endl;
+                    T3 end(where);
+                    while (end != e && *end != '\r' && *end != '\n') {
+                        ++end;
+                    }
+                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << ": \n" << std::string(get_line_start(b, where), end) << " ... \n" << std::setw(std::distance(b, where)) << '^' << "---- here\n";
+                    return qi::fail;
+                }
+            };
+            
+            // Functor used for annotating entities with line number information.
+            class PositionAnnotation {
+            public:
+                typedef void result_type;
+                
+                PositionAnnotation(Iterator first) : first(first) {
+                    // Intentionally left empty.
+                }
+
+                template<typename Entity, typename First, typename Last>
+                result_type operator()(Entity& entity, First f, Last l) const {
+                    entity.setLineNumber(get_line(f));
+                }
+            private:
+                std::string filename;
+                Iterator const first;
+            };
+            
             class PrismGrammar : public qi::grammar<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> {
             public:
                 /*!
-                 * Default constructor that creates an empty and functional grammar.
+                 * Creates a grammar for the given filename and the iterator to the first input to parse.
+                 *
+                 * @param filename The filename that is to be read. This is used for proper error reporting.
+                 * @param first The iterator to the beginning of the input.
+                 */
+                PrismGrammar(std::string const& filename, Iterator first);
+
+                /*!
+                 * Toggles whether or not expressions are generated.
                  */
-                PrismGrammar();
+                void toggleExpressionGeneration();
                 
             private:
+                // A flag that stores whether the grammar currently generates expressions or not.
+                bool doExpressionGeneration;
+                
+                /*!
+                 * Sets the expression generation to the desired value.
+                 *
+                 * @param doExpressionGeneration A flag that sets whether or not expressions are generated.
+                 */
+                void setExpressionGeneration(bool doExpressionGeneration);
+                
+                /*!
+                 * Sets whether doubles literals are allowed in the parsed expression.
+                 *
+                 * @param flag Indicates whether to allow or forbid double literals in the parsed expression.
+                 */
+                void allowDoubleLiterals(bool flag);
+                
+                // The name of the file being parsed.
+                std::string filename;
+
+                /*!
+                 * Retrieves the name of the file currently being parsed.
+                 *
+                 * @return The name of the file currently being parsed.
+                 */
+                std::string const& getFilename() const;
+                
+                // A function used for annotating the entities with their position.
+                phoenix::function<ErrorHandler> handler;
+                phoenix::function<PositionAnnotation> annotate;
+                
                 // The starting point of the grammar.
                 qi::rule<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
                 
@@ -103,14 +179,14 @@ namespace storm {
                 
                 // Rules for parsing the program header.
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedBooleanConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedIntegerConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> undefinedDoubleConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedBooleanConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedIntegerConstantDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> definedDoubleConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedDoubleConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedBooleanConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedIntegerConstantDefinition;
+                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedDoubleConstantDefinition;
                 
                 // Rules for global variable definitions.
                 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
@@ -119,81 +195,83 @@ namespace storm {
                 
                 // Rules for modules definition.
                 qi::rule<Iterator, std::vector<storm::prism::Module>(GlobalProgramInformation&), Skipper> moduleDefinitionList;
-                qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, storm::prism::BooleanVariable>, std::map<std::string, storm::prism::IntegerVariable>>, Skipper> moduleDefinition;
+                qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::vector<storm::prism::BooleanVariable>, std::vector<storm::prism::IntegerVariable>>, Skipper> moduleDefinition;
                 qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
                 
                 // Rules for variable definitions.
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::BooleanVariable>&, std::map<std::string, storm::prism::IntegerVariable>&), Skipper> variableDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::BooleanVariable>&), Skipper> booleanVariableDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::IntegerVariable>&), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
+                qi::rule<Iterator, qi::unused_type(std::vector<storm::prism::BooleanVariable>&, std::vector<storm::prism::IntegerVariable>&), Skipper> variableDefinition;
+                qi::rule<Iterator, storm::prism::BooleanVariable(), Skipper> booleanVariableDefinition;
+                qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
                 
                 // Rules for command definitions.
-                qi::rule<Iterator, storm::prism::Command(), qi::locals<std::string>, Skipper> commandDefinition;
-                qi::rule<Iterator, std::vector<storm::prism::Update>(), Skipper> updateListDefinition;
-                qi::rule<Iterator, storm::prism::Update(), qi::locals<std::map<std::string, storm::prism::Assignment>>, Skipper> updateDefinition;
-                qi::rule<Iterator, qi::unused_type(std::map<std::string, storm::prism::Assignment>&), Skipper> assignmentDefinitionList;
-                qi::rule<Iterator, storm::prism::Assignment(std::map<std::string, storm::prism::Assignment>&), Skipper> assignmentDefinition;
+                qi::rule<Iterator, storm::prism::Command(GlobalProgramInformation&), qi::locals<std::string>, Skipper> commandDefinition;
+                qi::rule<Iterator, std::vector<storm::prism::Update>(GlobalProgramInformation&), Skipper> updateListDefinition;
+                qi::rule<Iterator, storm::prism::Update(GlobalProgramInformation&), Skipper> updateDefinition;
+                qi::rule<Iterator, std::vector<storm::prism::Assignment>(), Skipper> assignmentDefinitionList;
+                qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
                 
                 // Rules for reward definitions.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), qi::locals<std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
+                qi::rule<Iterator, storm::prism::RewardModel(), qi::locals<std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
                 qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
                 qi::rule<Iterator, storm::prism::TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
                 
+                // Rules for initial states expression.
+                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> initialStatesConstruct;
+                
                 // Rules for label definitions.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> labelDefinition;
+                qi::rule<Iterator, storm::prism::Label(), Skipper> labelDefinition;
                 
                 // Rules for formula definitions.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> formulaDefinition;
+                qi::rule<Iterator, storm::prism::Formula(), Skipper> formulaDefinition;
                 
                 // Rules for identifier parsing.
                 qi::rule<Iterator, std::string(), Skipper> identifier;
                 
                 // Rules for parsing a composed expression.
                 qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> booleanExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), Skipper> orExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> notExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicBooleanExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> booleanVariableExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> numericalExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> multiplicationExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicNumericalExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> numericalVariableExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
+                qi::rule<Iterator, storm::expressions::Expression(), Skipper> identifierExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
                 qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
                 
+                // Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
+                boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
+                
                 // Parsers that recognize special keywords and model types.
                 storm::parser::prism::keywordsStruct keywords_;
                 storm::parser::prism::modelTypeStruct modelType_;
+                qi::symbols<char, storm::expressions::Expression> identifiers_;
                 
-                // Helper methods that add data to data structures.
-                static bool addUndefinedBooleanConstant(std::set<std::string>& undefinedBooleanConstants, std::string const& newUndefinedBooleanConstant);
-                static bool addUndefinedIntegerConstant(std::set<std::string>& undefinedIntegerConstants, std::string const& newUndefinedIntegerConstant);
-                static bool addUndefinedDoubleConstant(std::set<std::string>& undefinedDoubleConstants, std::string const& newUndefinedDoubleConstant);
-                
-                static bool addDefinedBooleanConstant(std::map<std::string, storm::expressions::Expression>& definedBooleanConstants, std::string const& newDefinedBooleanConstant, storm::expressions::Expression expression);
-                static bool addDefinedIntegerConstant(std::map<std::string, storm::expressions::Expression>& definedIntegerConstants, std::string const& newDefinedIntegerConstant, storm::expressions::Expression expression);
-                static bool addDefinedDoubleConstant(std::map<std::string, storm::expressions::Expression>& definedDoubleConstants, std::string const& newDefinedDoubleConstant, storm::expressions::Expression expression);
-
-                static bool addFormula(std::map<std::string, storm::expressions::Expression>& formulas, std::string const& formulaName, storm::expressions::Expression expression);
-                
-                static storm::prism::RewardModel addRewardModel(std::map<std::string, storm::prism::RewardModel>& rewardModels, std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards);
-                static storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression);
-                static storm::prism::TransitionReward createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression);
-                
-                static bool addLabel(std::map<std::string, storm::expressions::Expression>& labels, std::string const& labelName, storm::expressions::Expression expression);
-                
-                static bool addAssignment(std::map<std::string, storm::prism::Assignment>& assignments, std::string const& variableName, storm::expressions::Expression assignedExpression);
-                static storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::map<std::string, storm::prism::Assignment>& assignments);
-                static storm::prism::Command createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates);
-                static bool addBooleanVariable(std::map<std::string, storm::prism::BooleanVariable>& booleanVariables, std::string const& variableName, storm::expressions::Expression initialValueExpression);
-                static bool addIntegerVariable(std::map<std::string, storm::prism::IntegerVariable>& integerVariables, std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression);
-                static storm::prism::Module createModule(std::string const& moduleName, std::map<std::string, storm::prism::BooleanVariable> const& booleanVariables, std::map<std::string, storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands);
-                static storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation const& globalProgramInformation);
-                static storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation, std::vector<storm::prism::Module> const& modules);
+                // Helper methods used in the grammar.
+                bool isValidIdentifier(std::string const& identifier);
+                bool addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
+                storm::expressions::Expression getIdentifierExpression(std::string const& identifier) const;
+                storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
+                storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
+                storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
+                storm::prism::Constant createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
+                storm::prism::Constant createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
+                storm::prism::Constant createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
+                storm::prism::Formula createFormula(std::string const& formulaName, storm::expressions::Expression expression) const;
+                storm::prism::Label createLabel(std::string const& labelName, storm::expressions::Expression expression) const;
+                storm::prism::RewardModel createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const;
+                storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
+                storm::prism::TransitionReward createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
+                storm::prism::Assignment createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const;
+                storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const;
+                storm::prism::Command createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const;
+                storm::prism::BooleanVariable createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const;
+                storm::prism::IntegerVariable createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const;
+                storm::prism::Module createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const;
+                storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const;
+                storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation) const;
             };
         } // namespace prism
     } // namespace parser
diff --git a/src/parser/prismparser/PrismParser.cpp b/src/parser/prismparser/PrismParser.cpp
new file mode 100644
index 000000000..a261ba8cc
--- /dev/null
+++ b/src/parser/prismparser/PrismParser.cpp
@@ -0,0 +1,70 @@
+#include "src/parser/prismparser/PrismParser.h"
+#include "src/parser/prismparser/PrismGrammar.h"
+
+// If the parser fails due to ill-formed data, this exception is thrown.
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/WrongFormatException.h"
+
+// Needed for file IO.
+#include <fstream>
+#include <iomanip>
+#include <limits>
+
+namespace storm {
+    namespace parser {
+        storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) {
+            // Open file and initialize result.
+            std::ifstream inputFileStream(filename, std::ios::in);
+            LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file " << filename << ".");
+            
+            storm::prism::Program result;
+            
+            // Now try to parse the contents of the file.
+            try {
+                std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
+                result = parseFromString(fileContent, filename, typeCheck);
+            } catch(std::exception& e) {
+                // In case of an exception properly close the file before passing exception.
+                inputFileStream.close();
+                throw e;
+            }
+            
+            // Close the stream in case everything went smoothly and return result.
+            inputFileStream.close();
+            return result;
+        }
+        
+        storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool typeCheck) {
+            PositionIteratorType first(input.begin());
+            PositionIteratorType iter = first;
+            PositionIteratorType last(input.end());
+            
+            // Create empty result;
+            storm::prism::Program result;
+            
+            // Create grammar.
+            storm::parser::prism::PrismGrammar grammar(filename, first);
+            try {
+                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
+                bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
+                LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in first pass.");
+                if (typeCheck) {
+                    first = PositionIteratorType(input.begin());
+                    iter = first;
+                    last = PositionIteratorType(input.end());
+                    grammar.toggleExpressionGeneration();
+                    succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
+                    LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in second pass.");
+                }
+            } catch (qi::expectation_failure<PositionIteratorType> const& e) {
+                // If the parser expected content different than the one provided, display information about the location of the error.
+                std::size_t lineNumber = boost::spirit::get_line(e.first);
+                
+                // Now propagate exception.
+                LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << ".");
+            }
+            
+            return result;
+        }
+    } // namespace parser
+} // namespace storm
diff --git a/src/parser/prismparser/PrismParser.h b/src/parser/prismparser/PrismParser.h
new file mode 100644
index 000000000..35d2404a6
--- /dev/null
+++ b/src/parser/prismparser/PrismParser.h
@@ -0,0 +1,36 @@
+#ifndef STORM_PARSER_PRISMPARSER_H_
+#define STORM_PARSER_PRISMPARSER_H_
+
+// All classes of the intermediate representation are used.
+#include "src/storage/prism/Program.h"
+
+// Used for file input.
+#include <istream>
+
+namespace storm {
+    namespace parser {
+        class PrismParser {
+        public:
+            /*!
+             * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
+             *
+             * @param filename the name of the file to parse.
+             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
+             * @return The resulting PRISM program.
+             */
+            static storm::prism::Program parse(std::string const& filename, bool typeCheck = true);
+            
+            /*!
+             * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
+             *
+             * @param input The input string to parse.
+             * @param filename The name of the file from which the input was read.
+             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
+             * @return The resulting PRISM program.
+             */
+            static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool typeCheck = true);
+        };
+    } // namespace parser
+} // namespace storm
+
+#endif /* STORM_PARSER_PRISMPARSER_H_ */
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index 90ba44885..8cc30aa19 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -86,8 +86,8 @@ namespace storm {
         void BinaryBooleanFunctionExpression::printToStream(std::ostream& stream) const {
             stream << "(" << *this->getFirstOperand();
             switch (this->getOperatorType()) {
-                case OperatorType::And: stream << " && "; break;
-                case OperatorType::Or: stream << " || "; break;
+                case OperatorType::And: stream << " & "; break;
+                case OperatorType::Or: stream << " | "; break;
                 case OperatorType::Implies: stream << " => "; break;
                 case OperatorType::Iff: stream << " <=> "; break;
             }
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index b94d98db8..d72a683ac 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -124,6 +124,10 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new VariableExpression(ExpressionReturnType::Double, variableName)));
         }
         
+        Expression Expression::createUndefinedVariable(std::string const& variableName) {
+            return Expression(std::shared_ptr<BaseExpression>(new VariableExpression(ExpressionReturnType::Undefined, variableName)));
+        }
+        
         Expression Expression::createBooleanConstant(std::string const& constantName) {
             return Expression(std::shared_ptr<BaseExpression>(new BooleanConstantExpression(constantName)));
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index e7768432d..47ca6d721 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -33,6 +33,7 @@ namespace storm {
             static Expression createBooleanVariable(std::string const& variableName);
             static Expression createIntegerVariable(std::string const& variableName);
             static Expression createDoubleVariable(std::string const& variableName);
+            static Expression createUndefinedVariable(std::string const& variableName);
             static Expression createBooleanConstant(std::string const& constantName);
             static Expression createIntegerConstant(std::string const& constantName);
             static Expression createDoubleConstant(std::string const& constantName);
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
index 580a6c33a..d01ebe69d 100644
--- a/src/storage/prism/BooleanVariable.h
+++ b/src/storage/prism/BooleanVariable.h
@@ -23,7 +23,7 @@ namespace storm {
              * @param filename The filename in which the variable is defined.
              * @param lineNumber The line number in which the variable is defined.
              */
-            BooleanVariable(std::string const& variableName, std::string const& filename, uint_fast64_t lineNumber);
+            BooleanVariable(std::string const& variableName, std::string const& filename = "", uint_fast64_t lineNumber = 0);
 
             /*!
              * Creates a boolean variable with the given name and the given constant initial value expression.
@@ -33,7 +33,7 @@ namespace storm {
              * @param filename The filename in which the variable is defined.
              * @param lineNumber The line number in which the variable is defined.
              */
-            BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber);
+            BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given boolean variable and performs the provided renaming.
diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index 038884593..468e0da2b 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -6,14 +6,18 @@ namespace storm {
             // Nothing to do here.
         }
         
-        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), actionName(oldCommand.getActionName()), guardExpression(oldCommand.getGuardExpression().substitute<std::map>(renaming)), globalIndex(newGlobalIndex) {
+        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), actionName(oldCommand.getActionName()), guardExpression(oldCommand.getGuardExpression().substitute<std::map>(renaming)), globalIndex(newGlobalIndex) {
+            // Rename the action name of the command.
             auto const& namePair = renaming.find(this->actionName);
             if (namePair != renaming.end()) {
                 this->actionName = namePair->second;
             }
+            
+            // Rename the updates of the command.
             this->updates.reserve(oldCommand.getNumberOfUpdates());
             for (Update const& update : oldCommand.getUpdates()) {
-                this->updates.emplace_back(update, update.getGlobalIndex(), renaming, filename, lineNumber);
+                this->updates.emplace_back(update, newGlobalUpdateIndex, renaming, filename, lineNumber);
+                ++newGlobalUpdateIndex;
             }
         }
 
diff --git a/src/storage/prism/Command.h b/src/storage/prism/Command.h
index 5780c3dce..0173832e8 100644
--- a/src/storage/prism/Command.h
+++ b/src/storage/prism/Command.h
@@ -29,11 +29,12 @@ namespace storm {
              *
              * @param oldCommand The command to copy.
              * @param newGlobalIndex The global index of the copy of the command.
+             * @param newGlobalUpdateIndex The global starting index for the updates of the renamed command.
              * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
              * @param filename The filename in which the command is defined.
              * @param lineNumber The line number in which the command is defined.
              */
-            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Command() = default;
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 9791d9890..b57bf32d3 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -35,8 +35,9 @@ namespace storm {
             }
             stream << constant.getConstantName();
             if (constant.isDefined()) {
-                stream << " = " << constant.getExpression() << ";";
+                stream << " = " << constant.getExpression();
             }
+            stream << ";";
             return stream;
         }
     }
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index 47005e6cd..e025a8636 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -23,7 +23,7 @@ namespace storm {
         }
         
         std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable) {
-            stream << variable.getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << variable.getInitialValueExpression() << ";";
+            stream << variable.getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << " init " << variable.getInitialValueExpression() << ";";
             return stream;
         }
     } // namespace prism
diff --git a/src/storage/prism/LocatedInformation.cpp b/src/storage/prism/LocatedInformation.cpp
index 94d965e94..a5a493319 100644
--- a/src/storage/prism/LocatedInformation.cpp
+++ b/src/storage/prism/LocatedInformation.cpp
@@ -10,8 +10,16 @@ namespace storm {
             return this->filename;
         }
         
+        void LocatedInformation::setFilename(std::string const& filename) {
+            this->filename = filename;
+        }
+        
         uint_fast64_t LocatedInformation::getLineNumber() const {
             return this->lineNumber;
         }
+        
+        void LocatedInformation::setLineNumber(uint_fast64_t lineNumber) {
+            this->lineNumber = lineNumber;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/prism/LocatedInformation.h b/src/storage/prism/LocatedInformation.h
index 638734f9f..09921a871 100644
--- a/src/storage/prism/LocatedInformation.h
+++ b/src/storage/prism/LocatedInformation.h
@@ -29,12 +29,26 @@ namespace storm {
              */
             std::string const& getFilename() const;
             
+            /*!
+             * Sets the filename of this information.
+             *
+             * @param filename The new filename of this information.
+             */
+            void setFilename(std::string const& filename);
+            
             /*!
              * Retrieves the line number in which the information was found.
              *
              * @return The line number in which the information was found.
              */
             uint_fast64_t getLineNumber() const;
+            
+            /*!
+             * Sets the line number of this information.
+             *
+             * @param lineNumber The new line number for this information.
+             */
+            void setLineNumber(uint_fast64_t lineNumber);
 
         private:
             // The file in which the piece of information was found.
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 69abaa2b6..48544efff 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -6,19 +6,18 @@
 namespace storm {
     namespace prism {
         Module::Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), booleanVariableToIndexMap(), integerVariables(integerVariables), integerVariableToIndexMap(), commands(commands), actions(), actionsToCommandIndexMap() {
-            // FIXME: construct mappings from variable names to their indices.
             // Initialize the internal mappings for fast information retrieval.
-            this->collectActions();
+            this->createMappings();
         }
         
-        Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
+        Module::Module(Module const& oldModule, std::string const& newModuleName, uint_fast64_t newGlobalCommandIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
             // Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception is thrown.
             for (auto const& booleanVariable : oldModule.getBooleanVariables()) {
                 auto const& renamingPair = renaming.find(booleanVariable.getName());
                 LOG_THROW(renamingPair != renaming.end(), storm::exceptions::InvalidArgumentException, "Boolean variable '" << booleanVariable.getName() << " was not renamed.");
                 this->booleanVariables.emplace_back(booleanVariable, renamingPair->second, renaming, filename, lineNumber);
             }
-            
+           
             // Now do the same for the integer variables.
             for (auto const& integerVariable : oldModule.getIntegerVariables()) {
                 auto const& renamingPair = renaming.find(integerVariable.getName());
@@ -26,16 +25,16 @@ namespace storm {
                 this->integerVariables.emplace_back(integerVariable, renamingPair->second, renaming, filename, lineNumber);
             }
             
-            // FIXME: construct mappings from variable names to their indices.
-            
             // Now we are ready to clone all commands and rename them if requested.
             this->commands.reserve(oldModule.getNumberOfCommands());
             for (Command const& command : oldModule.getCommands()) {
-                this->commands.emplace_back(command, command.getGlobalIndex(), renaming);
+                this->commands.emplace_back(command, newGlobalCommandIndex, newGlobalUpdateIndex, renaming, filename, lineNumber);
+                ++newGlobalCommandIndex;
+                newGlobalUpdateIndex += this->commands.back().getNumberOfUpdates();
             }
             
-            // Finally, update internal mapping.
-            this->collectActions();
+            // Finally, update internal mappings.
+            this->createMappings();
         }
         
         std::size_t Module::getNumberOfBooleanVariables() const {
@@ -108,18 +107,28 @@ namespace storm {
             LOG_THROW(false, storm::exceptions::OutOfRangeException, "Action name '" << action << "' does not exist in module.");
         }
         
-        void Module::collectActions() {
-            // Clear the current mapping.
+        void Module::createMappings() {
+            // Clear the current mappings.
             this->actionsToCommandIndexMap.clear();
+            this->booleanVariableToIndexMap.clear();
+            this->integerVariableToIndexMap.clear();
+            
+            // Create the mappings for the variables.
+            for (uint_fast64_t i = 0; i < this->booleanVariables.size(); ++i) {
+                this->booleanVariableToIndexMap[this->getBooleanVariables()[i].getName()] = i;
+            }
+            for (uint_fast64_t i = 0; i < this->integerVariables.size(); ++i) {
+                this->integerVariableToIndexMap[this->getIntegerVariables()[i].getName()] = i;
+            }
             
             // Add the mapping for all commands.
-            for (unsigned int id = 0; id < this->commands.size(); id++) {
-                std::string const& action = this->commands[id].getActionName();
+            for (uint_fast64_t i = 0; i < this->commands.size(); i++) {
+                std::string const& action = this->commands[i].getActionName();
                 if (action != "") {
                     if (this->actionsToCommandIndexMap.find(action) == this->actionsToCommandIndexMap.end()) {
                         this->actionsToCommandIndexMap.emplace(action, std::set<uint_fast64_t>());
                     }
-                    this->actionsToCommandIndexMap[action].insert(id);
+                    this->actionsToCommandIndexMap[action].insert(i);
                     this->actions.insert(action);
                 }
             }
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index cb62bc626..4a1608d22 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -34,11 +34,13 @@ namespace storm {
              *
              * @param oldModule The module to be copied.
              * @param newModuleName The name of the new module.
+             * @param newGlobalCommandIndex The global starting index for commands of the renamed module.
+             * @param newGlobalUpdateIndex The global starting index for the updates of the renamed module.
              * @param renaming A mapping of identifiers to the new identifiers they are to be replaced with.
              * @param filename The filename in which the module is defined.
              * @param lineNumber The line number in which the module is defined.
              */
-            Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Module(Module const& oldModule, std::string const& newModuleName, uint_fast64_t newGlobalCommandIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Module() = default;
@@ -164,7 +166,7 @@ namespace storm {
             /*!
              * Computes the locally maintained mappings for fast data retrieval.
              */
-            void collectActions();
+            void createMappings();
             
             // The name of the module.
             std::string moduleName;
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 281be2531..98bb75a1a 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -5,29 +5,8 @@
 
 namespace storm {
     namespace prism {
-        Program::Program(ModelType modelType, std::vector<Constant> const& undefinedConstants, std::vector<Constant> const& definedConstants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), undefinedConstants(undefinedConstants), definedConstants(definedConstants), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
-            // FIXME: build the mappings for constants, formulas, modules, global variables, reward models and labels.
-            // Now build the mapping from action names to module indices so that the lookup can later be performed quickly.
-            for (unsigned int moduleIndex = 0; moduleIndex < this->getNumberOfModules(); moduleIndex++) {
-                Module const& module = this->getModule(moduleIndex);
-                
-                for (auto const& action : module.getActions()) {
-                    auto const& actionModuleIndicesPair = this->actionsToModuleIndexMap.find(action);
-                    if (actionModuleIndicesPair == this->actionsToModuleIndexMap.end()) {
-                        this->actionsToModuleIndexMap[action] = std::set<uint_fast64_t>();
-                    }
-                    this->actionsToModuleIndexMap[action].insert(moduleIndex);
-                    this->actions.insert(action);
-                }
-                
-                // Put in the appropriate entries for the mapping from variable names to module index.
-                for (auto const& booleanVariable : module.getBooleanVariables()) {
-                    this->variableToModuleIndexMap[booleanVariable.getName()] = moduleIndex;
-                }
-                for (auto const& integerVariable : module.getBooleanVariables()) {
-                    this->variableToModuleIndexMap[integerVariable.getName()] = moduleIndex;
-                }
-            }
+        Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+            this->createMappings();
         }
         
         Program::ModelType Program::getModelType() const {
@@ -35,15 +14,16 @@ namespace storm {
         }
         
         bool Program::hasUndefinedConstants() const {
-            return this->undefinedConstants.size() > 0;
-        }
-        
-        std::vector<Constant> const& Program::getUndefinedConstants() const {
-            return this->undefinedConstants;
+            for (auto const& constant : this->getConstants()) {
+                if (!constant.isDefined()) {
+                    return true;
+                }
+            }
+            return true;
         }
         
-        std::vector<Constant> const& Program::getDefinedConstants() const {
-            return this->definedConstants;
+        std::vector<Constant> const& Program::getConstants() const {
+            return this->constants;
         }
 
         std::vector<BooleanVariable> const& Program::getGlobalBooleanVariables() const {
@@ -78,6 +58,10 @@ namespace storm {
             return this->formulas;
         }
         
+        std::size_t Program::getNumberOfFormulas() const {
+            return this->formulas.size();
+        }
+        
         std::size_t Program::getNumberOfModules() const {
             return this->getModules().size();
         }
@@ -140,6 +124,10 @@ namespace storm {
             return this->rewardModels;
         }
         
+        std::size_t Program::getNumberOfRewardModels() const {
+            return this->rewardModels.size();
+        }
+        
         storm::prism::RewardModel const& Program::getRewardModel(std::string const& name) const {
             auto const& nameIndexPair = this->rewardModelToIndexMap.find(name);
             LOG_THROW(nameIndexPair != this->rewardModelToIndexMap.end(), storm::exceptions::OutOfRangeException, "Reward model '" << name << "' does not exist.");
@@ -150,6 +138,10 @@ namespace storm {
             return this->labels;
         }
         
+        std::size_t Program::getNumberOfLabels() const {
+            return this->labels.size();
+        }
+        
         Program Program::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
             std::vector<storm::prism::Module> newModules;
             newModules.reserve(this->getNumberOfModules());
@@ -158,7 +150,52 @@ namespace storm {
                 newModules.push_back(module.restrictCommands(indexSet));
             }
             
-            return Program(this->getModelType(), this->getUndefinedConstants(), this->getDefinedConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+            return Program(this->getModelType(), this->getConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+        }
+        
+        void Program::createMappings() {
+            // Build the mappings for global variables, formulas, modules, reward models and labels.
+            for (uint_fast64_t globalVariableIndex = 0; globalVariableIndex < this->getNumberOfGlobalBooleanVariables(); ++globalVariableIndex) {
+                this->globalBooleanVariableToIndexMap[this->getGlobalBooleanVariables()[globalVariableIndex].getName()] = globalVariableIndex;
+            }
+            for (uint_fast64_t globalVariableIndex = 0; globalVariableIndex < this->getNumberOfGlobalIntegerVariables(); ++globalVariableIndex) {
+                this->globalIntegerVariableToIndexMap[this->getGlobalIntegerVariables()[globalVariableIndex].getName()] = globalVariableIndex;
+            }
+            for (uint_fast64_t formulaIndex = 0; formulaIndex < this->getNumberOfFormulas(); ++formulaIndex) {
+                this->formulaToIndexMap[this->getFormulas()[formulaIndex].getFormulaName()] = formulaIndex;
+            }
+            for (uint_fast64_t moduleIndex = 0; moduleIndex < this->getNumberOfModules(); ++moduleIndex) {
+                this->moduleToIndexMap[this->getModules()[moduleIndex].getName()] = moduleIndex;
+            }
+            for (uint_fast64_t rewardModelIndex = 0; rewardModelIndex < this->getNumberOfRewardModels(); ++rewardModelIndex) {
+                this->rewardModelToIndexMap[this->getRewardModels()[rewardModelIndex].getName()] = rewardModelIndex;
+            }
+            for (uint_fast64_t labelIndex = 0; labelIndex < this->getNumberOfLabels(); ++labelIndex) {
+                this->labelToIndexMap[this->getLabels()[labelIndex].getLabelName()] = labelIndex;
+            }
+            
+            // Build the mapping from action names to module indices so that the lookup can later be performed quickly.
+            for (unsigned int moduleIndex = 0; moduleIndex < this->getNumberOfModules(); moduleIndex++) {
+                Module const& module = this->getModule(moduleIndex);
+                
+                for (auto const& action : module.getActions()) {
+                    auto const& actionModuleIndicesPair = this->actionsToModuleIndexMap.find(action);
+                    if (actionModuleIndicesPair == this->actionsToModuleIndexMap.end()) {
+                        this->actionsToModuleIndexMap[action] = std::set<uint_fast64_t>();
+                    }
+                    this->actionsToModuleIndexMap[action].insert(moduleIndex);
+                    this->actions.insert(action);
+                }
+                
+                // Put in the appropriate entries for the mapping from variable names to module index.
+                for (auto const& booleanVariable : module.getBooleanVariables()) {
+                    this->variableToModuleIndexMap[booleanVariable.getName()] = moduleIndex;
+                }
+                for (auto const& integerVariable : module.getBooleanVariables()) {
+                    this->variableToModuleIndexMap[integerVariable.getName()] = moduleIndex;
+                }
+            }
+
         }
         
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
@@ -172,7 +209,7 @@ namespace storm {
             }
             stream << std::endl;
             
-            for (auto const& constant : program.getUndefinedConstants()) {
+            for (auto const& constant : program.getConstants()) {
                 stream << constant << std::endl;
             }
             stream << std::endl;
@@ -185,6 +222,11 @@ namespace storm {
             }
             stream << std::endl;
             
+            for (auto const& formula : program.getFormulas()) {
+                stream << formula << std::endl;
+            }
+            stream << std::endl;
+            
             for (auto const& module : program.getModules()) {
                 stream << module << std::endl;
             }
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 0dbfc20fc..93e8ffccd 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -27,8 +27,7 @@ namespace storm {
              * models, labels and initial states.
              *
              * @param modelType The type of the program.
-             * @param undefinedConstants The undefined constants of the program.
-             * @param definedConstants The defined integer constants of the program.
+             * @param constants The constants of the program.
              * @param globalBooleanVariables The global boolean variables of the program.
              * @param globalIntegerVariables The global integer variables of the program.
              * @param formulas The formulas defined in the program.
@@ -43,7 +42,7 @@ namespace storm {
              * @param filename The filename in which the program is defined.
              * @param lineNumber The line number in which the program is defined.
              */
-            Program(ModelType modelType, std::vector<Constant> const& undefinedConstants, std::vector<Constant> const& definedConstants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Provide default implementations for constructors and assignments.
             Program() = default;
@@ -65,21 +64,14 @@ namespace storm {
              * @return True iff there are undefined constants of any type in the program.
              */
             bool hasUndefinedConstants() const;
-            
-            /*!
-             * Retrieves the undefined constants of the program.
-             *
-             * @return The undefined constants of the program.
-             */
-            std::vector<Constant> const& getUndefinedConstants() const;
 
             /*!
-             * Retrieves the defined constants of the program.
+             * Retrieves all constants defined in the program.
              *
-             * @return The defined constants of the program.
+             * @return The constants defined in the program.
              */
-            std::vector<Constant> const& getDefinedConstants() const;
-
+            std::vector<Constant> const& getConstants() const;
+            
             /*!
              * Retrieves the global boolean variables of the program.
              *
@@ -131,6 +123,13 @@ namespace storm {
              */
             std::vector<Formula> const& getFormulas() const;
             
+            /*!
+             * Retrieves the number of formulas in the program.
+             *
+             * @return The number of formulas in the program.
+             */
+            std::size_t getNumberOfFormulas() const;
+            
             /*!
              * Retrieves the number of modules in the program.
              *
@@ -206,6 +205,13 @@ namespace storm {
              */
             std::vector<RewardModel> const& getRewardModels() const;
             
+            /*!
+             * Retrieves the number of reward models in the program.
+             *
+             * @return The number of reward models in the program.
+             */
+            std::size_t getNumberOfRewardModels() const;
+            
             /*!
              * Retrieves the reward model with the given name.
              *
@@ -221,6 +227,13 @@ namespace storm {
              */
             std::vector<Label> const& getLabels() const;
             
+            /*!
+             * Retrieves the number of labels in the program.
+             *
+             * @return The number of labels in the program.
+             */
+            std::size_t getNumberOfLabels() const;
+
             /*!
              * Creates a new program that drops all commands whose indices are not in the given set.
              *
@@ -231,14 +244,14 @@ namespace storm {
             friend std::ostream& operator<<(std::ostream& stream, Program const& program);
             
         private:
+            // Creates the internal mappings.
+            void createMappings();
+            
             // The type of the model.
             ModelType modelType;
             
             // The undefined constants of the program.
-            std::vector<Constant> undefinedConstants;
-            
-            // The defined constants of the program.
-            std::vector<Constant> definedConstants;
+            std::vector<Constant> constants;
 
             // The global boolean variables.
             std::vector<BooleanVariable> globalBooleanVariables;
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index 123a16286..dc609b4ad 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -5,10 +5,11 @@
 namespace storm {
     namespace prism {
         Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(likelihoodExpression), assignments(assignments), variableToAssignmentIndexMap(), globalIndex(globalIndex) {
-            // FIXME: construct the mapping from variable names to assignments and check for uniqueness.
+            this->createAssignmentMapping();
         }
         
         Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), assignments(), variableToAssignmentIndexMap(), globalIndex(newGlobalIndex) {
+            // Rename all assignments.
             for (auto const& assignment : update.getAssignments()) {
                 auto const& namePair = renaming.find(assignment.getVariableName());
                 if (namePair != renaming.end()) {
@@ -17,8 +18,9 @@ namespace storm {
                     this->assignments.emplace_back(Assignment(assignment));
                 }
             }
-            // FIXME: construct the mapping from variable names to assignments and check for uniqueness.
-            this->likelihoodExpression = update.getLikelihoodExpression().substitute<std::map>(renaming);
+
+            // Create the assignment mapping.
+            this->createAssignmentMapping();
         }
         
         storm::expressions::Expression const& Update::getLikelihoodExpression() const {
@@ -43,6 +45,13 @@ namespace storm {
             return this->globalIndex;
         }
         
+        void Update::createAssignmentMapping() {
+            this->variableToAssignmentIndexMap.clear();
+            for (uint_fast64_t assignmentIndex = 0; assignmentIndex < this->getAssignments().size(); ++assignmentIndex) {
+                this->variableToAssignmentIndexMap[this->getAssignments()[assignmentIndex].getVariableName()] = assignmentIndex;
+            }
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Update const& update) {
             stream << update.getLikelihoodExpression() << " : ";
             uint_fast64_t i = 0;
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index 3a2ce087f..6f85ece29 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -77,6 +77,11 @@ namespace storm {
             friend std::ostream& operator<<(std::ostream& stream, Update const& assignment);
             
         private:
+            /*!
+             * Creates the internal mapping of variables to their assignments.
+             */
+            void createAssignmentMapping();
+            
             // An expression specifying the likelihood of taking this update.
             storm::expressions::Expression likelihoodExpression;
             
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
new file mode 100644
index 000000000..1729ba036
--- /dev/null
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -0,0 +1,157 @@
+#include "gtest/gtest.h"
+#include "storm-config.h"
+#include "src/parser/prismparser/PrismParser.h"
+
+TEST(PrismParser, SimpleParsingOnlyTest) {
+    std::string testInput =
+    R"(dtmc
+    module mod1
+        b : bool;
+        [a] true -> 1: (b'=true);
+    endmodule)";
+    
+    storm::prism::Program result;
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false));
+    EXPECT_EQ(1, result.getNumberOfModules());
+    EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType());
+}
+
+TEST(PrismParser, StandardModelParsingTest) {
+    storm::prism::Program result;
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/die.pm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/firewire.nm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3_5.pm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/two_dice.nm", false));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm", false));
+}
+
+TEST(PrismParser, SimpleFullTest) {
+    std::string testInput =
+    R"(dtmc
+    module mod1
+        b : bool;
+        [a] true -> 1: (b'=true);
+    endmodule)";
+    
+    storm::prism::Program result;
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true));
+    EXPECT_EQ(1, result.getNumberOfModules());
+    EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType());
+}
+
+TEST(PrismParser, ComplexFullTest) {
+    std::string testInput =
+    R"(ma
+    
+    const int a;
+    const int b = 10;
+    const bool c;
+    const bool d = true | false;
+    const double e;
+    const double f = 9;
+    
+    formula test = a >= 10 & (max(a,b) > floor(e));
+    formula test2 = a+b;
+    
+    global g : bool init false;
+    global h : [0 .. b];
+    
+    module mod1
+        i : bool;
+        j : bool init c;
+        k : [125..a] init a;
+
+        [a] test2&false -> (i'=true)&(h'=1+1) + 1 : (j'=floor(a) <= max(k, b) - 1 + k);
+    endmodule
+                                              
+    module mod2
+        [b] (k > 3) & false & (min(a, 0) < max(h, k)) -> 1-e: (j'=(1-a) * 2 + floor(f));
+    endmodule
+    
+    module mod3 = mod2 [ x = y ] endmodule
+                                                               
+    label "mal" = max(a, 10) > 0;
+                                                               
+    init
+        true
+    endinit
+    
+    rewards "testrewards"
+        [stateRew] true : a + 7;
+        max(f, a) <= 8 : 2*b;
+    endrewards
+                                                               
+    rewards "testrewards2"
+        [stateRew] true : a + 7;
+        max(f, a) <= 8 : 2*b;
+    endrewards)";
+    
+    storm::prism::Program result;
+    result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true);
+    std::cout << result << std::endl;
+    EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType());
+    EXPECT_EQ(3, result.getNumberOfModules());
+    EXPECT_EQ(2, result.getNumberOfRewardModels());
+    EXPECT_EQ(1, result.getNumberOfLabels());
+    EXPECT_TRUE(result.definesInitialStatesExpression());
+}
+
+TEST(PrismParser, ComplexParsingTest) {
+    std::string testInput =
+    R"(ma
+    
+    const int a;
+    const int b = 10;
+    const bool c;
+    const bool d = true | false;
+    const double e;
+    const double f = 9;
+    
+    formula test = (a >= 10 & (max(a, b) > floor(e)));
+
+    global g : bool init false;
+    global h : [0 .. b];
+    
+    module mod1
+        i : bool;
+        j : bool init c;
+        k : [125..a] init a;
+        [a] true -> (i'=true)&(h'=1+1) + 1 : (j'=floor(a) <= max(k, b) - 1 + k);
+    endmodule
+                                    
+    module mod2
+        [b] (x > 3) & false & (min(a, b0) < max(as8, b)) -> y: (x'=(1-g) * 2 + a);
+        [] s=1 -> (a'=a);
+        [read] c<N-1 -> 1 : (c'=floor(c) + 1);
+    endmodule
+                             
+    module mod3 = mod2 [ x = y ] endmodule
+             
+    label "mal" = max(x, i) > 0;
+                             
+    init
+        true
+    endinit
+                             
+    rewards "testrewards"
+        [stateRew] true : a + 7;
+        max(z, f) <= 8 : 2*b;
+    endrewards
+                             
+    rewards "testrewards2"
+        [stateRew] true : a + 7;
+        max(z, f) <= 8 : 2*b;
+    endrewards)";
+    
+    storm::prism::Program result;
+    result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false);
+    EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType());
+    EXPECT_EQ(3, result.getNumberOfModules());
+    EXPECT_EQ(2, result.getNumberOfRewardModels());
+    EXPECT_EQ(1, result.getNumberOfLabels());
+    EXPECT_TRUE(result.definesInitialStatesExpression());
+}
\ No newline at end of file

From 199b6576a991a82813ad24015ef94a7f0a3f44c4 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 13 Apr 2014 23:08:51 +0200
Subject: [PATCH 070/147] Added ternary operator. Parsing standard PRISM models
 into the PRISM classes now works. Included tests for parsing stuff. ToDo: add
 remaining semantic checks for parsing/PRISM classes and fix explicit model
 adapter.

Former-commit-id: cb37c98f1f676e148f3d4589bced38bb253ba4bc
---
 src/parser/PrismParser.cpp                    | 636 ++++++++++++++++++
 src/parser/PrismParser.h                      | 320 +++++++++
 src/parser/prismparser/PrismGrammar.cpp       | 373 ----------
 src/parser/prismparser/PrismGrammar.h         | 282 --------
 src/parser/prismparser/PrismParser.cpp        |  70 --
 src/parser/prismparser/PrismParser.h          |  36 -
 src/storage/expressions/BaseExpression.cpp    |   5 +
 src/storage/expressions/BaseExpression.h      |   2 +
 src/storage/expressions/Expression.cpp        |   7 +
 src/storage/expressions/Expression.h          |   1 +
 src/storage/expressions/ExpressionVisitor.h   |   2 +
 .../IdentifierSubstitutionVisitor.cpp         |  23 +
 .../IdentifierSubstitutionVisitor.h           |   1 +
 .../expressions/IfThenElseExpression.cpp      |  96 +++
 .../expressions/IfThenElseExpression.h        |  74 ++
 .../expressions/SubstitutionVisitor.cpp       |  23 +
 src/storage/expressions/SubstitutionVisitor.h |   1 +
 src/storage/prism/Assignment.cpp              |   7 -
 src/storage/prism/Assignment.h                |  12 +-
 src/storage/prism/BooleanVariable.cpp         |   4 -
 src/storage/prism/BooleanVariable.h           |  12 -
 src/storage/prism/Command.cpp                 |  15 -
 src/storage/prism/Command.h                   |  12 -
 src/storage/prism/IntegerVariable.cpp         |   4 -
 src/storage/prism/IntegerVariable.h           |  11 -
 src/storage/prism/Module.cpp                  |  29 +-
 src/storage/prism/Module.h                    |  14 -
 src/storage/prism/Update.cpp                  |  15 -
 src/storage/prism/Update.h                    |  11 -
 test/functional/parser/PrismParserTest.cpp    |  21 +-
 test/functional/storage/ExpressionTest.cpp    |  13 +
 31 files changed, 1223 insertions(+), 909 deletions(-)
 create mode 100644 src/parser/PrismParser.cpp
 create mode 100644 src/parser/PrismParser.h
 delete mode 100644 src/parser/prismparser/PrismGrammar.cpp
 delete mode 100644 src/parser/prismparser/PrismGrammar.h
 delete mode 100644 src/parser/prismparser/PrismParser.cpp
 delete mode 100644 src/parser/prismparser/PrismParser.h
 create mode 100644 src/storage/expressions/IfThenElseExpression.cpp
 create mode 100644 src/storage/expressions/IfThenElseExpression.h

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
new file mode 100644
index 000000000..71843541b
--- /dev/null
+++ b/src/parser/PrismParser.cpp
@@ -0,0 +1,636 @@
+#include "src/parser/PrismParser.h"
+#include "src/exceptions/InvalidArgumentException.h"
+#include "src/exceptions/WrongFormatException.h"
+
+namespace storm {
+    namespace parser {
+        storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) {
+            // Open file and initialize result.
+            std::ifstream inputFileStream(filename, std::ios::in);
+            LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file " << filename << ".");
+            
+            storm::prism::Program result;
+            
+            // Now try to parse the contents of the file.
+            try {
+                std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
+                result = parseFromString(fileContent, filename, typeCheck);
+            } catch(std::exception& e) {
+                // In case of an exception properly close the file before passing exception.
+                inputFileStream.close();
+                throw e;
+            }
+            
+            // Close the stream in case everything went smoothly and return result.
+            inputFileStream.close();
+            return result;
+        }
+        
+        storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool typeCheck) {
+            PositionIteratorType first(input.begin());
+            PositionIteratorType iter = first;
+            PositionIteratorType last(input.end());
+            
+            // Create empty result;
+            storm::prism::Program result;
+            
+            // Create grammar.
+            storm::parser::PrismParser grammar(filename, first);
+            try {
+                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
+                bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
+                LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in first pass.");
+                if (typeCheck) {
+                    first = PositionIteratorType(input.begin());
+                    iter = first;
+                    last = PositionIteratorType(input.end());
+                    grammar.moveToSecondRun();
+                    succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
+                    LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in second pass.");
+                }
+            } catch (qi::expectation_failure<PositionIteratorType> const& e) {
+                // If the parser expected content different than the one provided, display information about the location of the error.
+                std::size_t lineNumber = boost::spirit::get_line(e.first);
+                
+                // Now propagate exception.
+                LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << ".");
+            }
+            
+            return result;
+        }
+        
+        PrismParser::PrismParser(std::string const& filename, Iterator first) : PrismParser::base_type(start), secondRun(false), allowDoubleLiteralsFlag(true), filename(filename), annotate(first) {
+            // Parse simple identifier.
+            identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&PrismParser::isValidIdentifier, phoenix::ref(*this), qi::_1)];
+            identifier.name("identifier");
+            
+            floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createFloorExpression, phoenix::ref(*this), qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createCeilExpression, phoenix::ref(*this), qi::_1)]];
+            floorCeilExpression.name("floor/ceil expression");
+            
+            minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createMinimumExpression, phoenix::ref(*this), qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMaximumExpression, phoenix::ref(*this), qi::_1, qi::_2)]];
+            minMaxExpression.name("min/max expression");
+            
+            identifierExpression = identifier[qi::_val = phoenix::bind(&PrismParser::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
+            identifierExpression.name("identifier expression");
+            
+            literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&PrismParser::createTrueExpression, phoenix::ref(*this))] | qi::lit("false")[qi::_val = phoenix::bind(&PrismParser::createFalseExpression, phoenix::ref(*this))] | strict_double[qi::_val = phoenix::bind(&PrismParser::createDoubleLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)] | qi::int_[qi::_val = phoenix::bind(&PrismParser::createIntegerLiteralExpression, phoenix::ref(*this), qi::_1)];
+            literalExpression.name("literal expression");
+            
+            atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression;
+            atomicExpression.name("atomic expression");
+            
+            unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = phoenix::bind(&PrismParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_1)];
+            unaryExpression.name("unary expression");
+            
+            multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]);
+            multiplicationExpression.name("multiplication expression");
+            
+            plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
+            plusExpression.name("plus expression");
+            
+            relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createNotEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
+            relativeExpression.name("relative expression");
+            
+            andExpression = relativeExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> relativeExpression)[qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
+            andExpression.name("and expression");
+            
+            orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&PrismParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)];
+            orExpression.name("or expression");
+            
+            iteExpression = orExpression[qi::_val = qi::_1] >> -(qi::lit("?") > orExpression > qi::lit(":") > orExpression)[qi::_val = phoenix::bind(&PrismParser::createIteExpression, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
+            iteExpression.name("if-then-else expression");
+            
+            expression %= iteExpression;
+            expression.name("expression");
+            
+            modelTypeDefinition %= modelType_;
+            modelTypeDefinition.name("model type");
+            
+            undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createUndefinedBooleanConstant, phoenix::ref(*this), qi::_1)];
+            undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
+            
+            undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createUndefinedIntegerConstant, phoenix::ref(*this), qi::_1)];
+            undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
+            
+            undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createUndefinedDoubleConstant, phoenix::ref(*this), qi::_1)];
+            undefinedDoubleConstantDefinition.name("undefined double constant definition");
+            
+            undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition);
+            undefinedConstantDefinition.name("undefined constant definition");
+            
+            definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)];
+            definedBooleanConstantDefinition.name("defined boolean constant declaration");
+            
+            definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)];
+            definedIntegerConstantDefinition.name("defined integer constant declaration");
+            
+            definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)];
+            definedDoubleConstantDefinition.name("defined double constant declaration");
+            
+            definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
+            definedConstantDefinition.name("defined constant definition");
+            
+            formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            formulaDefinition.name("formula definition");
+            
+            booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)];
+            booleanVariableDefinition.name("boolean variable definition");
+            
+            integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression[qi::_a = qi::_1] > qi::lit("..") > expression > qi::lit("]")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)];
+            integerVariableDefinition.name("integer variable definition");
+            
+            variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]);
+            variableDefinition.name("variable declaration");
+            
+            globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)]));
+            globalVariableDefinition.name("global variable declaration list");
+            
+            programHeader = modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
+            >   *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)] | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)])
+            >   *(formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1)])
+            >   *(globalVariableDefinition(qi::_r1));
+            programHeader.name("program header");
+            
+            stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
+            stateRewardDefinition.name("state reward definition");
+            
+            transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
+            transitionRewardDefinition.name("transition reward definition");
+            
+            rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"")
+                                     > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)]
+                                         |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
+                                         )
+                                     >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismParser::createRewardModel, phoenix::ref(*this), qi::_1, qi::_a, qi::_b)];
+            rewardModelDefinition.name("reward model definition");
+            
+            initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)];
+            initialStatesConstruct.name("initial construct");
+            
+            labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
+            labelDefinition.name("label definition");
+            
+            assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&PrismParser::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)];
+            assignmentDefinition.name("assignment");
+            
+            assignmentDefinitionList %= +assignmentDefinition % "&";
+            assignmentDefinitionList.name("assignment list");
+            
+            updateDefinition = (((plusExpression > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismParser::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)];
+            updateDefinition.name("update");
+            
+            updateListDefinition %= +updateDefinition(qi::_r1) % "+";
+            updateListDefinition.name("update list");
+            
+            commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)];
+            commandDefinition.name("command definition");
+            
+            moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition(qi::_r1) > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismParser::createModule, phoenix::ref(*this), qi::_1, qi::_a, qi::_b, qi::_2, qi::_r1)];
+            moduleDefinition.name("module definition");
+            
+            moduleRenaming = ((qi::lit("module") >> identifier >> qi::lit("=")) > identifier > qi::lit("[")
+                              > ((identifier > qi::lit("=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))] % ",") > qi::lit("]")
+                              > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismParser::createRenamedModule, phoenix::ref(*this), qi::_1, qi::_2, qi::_a, qi::_r1)];
+            moduleRenaming.name("module definition via renaming");
+            
+            moduleDefinitionList %= +(moduleRenaming(qi::_r1) | moduleDefinition(qi::_r1))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_r1), qi::_1)];
+            moduleDefinitionList.name("module list");
+            
+            start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(initialStatesConstruct(qi::_a) | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)] | formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_a), qi::_1)]) > qi::eoi)[qi::_val = phoenix::bind(&PrismParser::createProgram, phoenix::ref(*this), qi::_a)];
+            start.name("probabilistic program");
+            
+            // Enable error reporting.
+            qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(iteExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            
+            // Enable location tracking for important entities.
+            auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
+            qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction);
+            qi::on_success(undefinedIntegerConstantDefinition, setLocationInfoFunction);
+            qi::on_success(undefinedDoubleConstantDefinition, setLocationInfoFunction);
+            qi::on_success(definedBooleanConstantDefinition, setLocationInfoFunction);
+            qi::on_success(definedIntegerConstantDefinition, setLocationInfoFunction);
+            qi::on_success(definedDoubleConstantDefinition, setLocationInfoFunction);
+            qi::on_success(booleanVariableDefinition, setLocationInfoFunction);
+            qi::on_success(integerVariableDefinition, setLocationInfoFunction);
+            qi::on_success(moduleDefinition, setLocationInfoFunction);
+            qi::on_success(moduleRenaming, setLocationInfoFunction);
+            qi::on_success(formulaDefinition, setLocationInfoFunction);
+            qi::on_success(rewardModelDefinition, setLocationInfoFunction);
+            qi::on_success(labelDefinition, setLocationInfoFunction);
+            qi::on_success(commandDefinition, setLocationInfoFunction);
+            qi::on_success(updateDefinition, setLocationInfoFunction);
+            qi::on_success(assignmentDefinition, setLocationInfoFunction);
+        }
+        
+        void PrismParser::moveToSecondRun() {
+            this->secondRun = true;
+        }
+        
+        void PrismParser::allowDoubleLiterals(bool flag) {
+            this->allowDoubleLiteralsFlag = flag;
+        }
+        
+        std::string const& PrismParser::getFilename() const {
+            return this->filename;
+        }
+        
+        bool PrismParser::isValidIdentifier(std::string const& identifier) {
+            if (this->keywords_.find(identifier) != nullptr) {
+                return false;
+            }
+            return true;
+        }
+        
+        bool PrismParser::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
+            LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::InvalidArgumentException, "Program must not define two initial constructs.");
+            if (globalProgramInformation.hasInitialStatesExpression) {
+                return false;
+            }
+            globalProgramInformation.hasInitialStatesExpression = true;
+            globalProgramInformation.initialStatesExpression = initialStatesExpression;
+            return true;
+        }
+        
+        storm::expressions::Expression PrismParser::createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1.ite(e2, e3);
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 || e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 && e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 > e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 >= e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 < e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 <= e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 == e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 != e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 + e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 - e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 * e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 / e2;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createNotExpression(storm::expressions::Expression e1) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return !e1;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createMinusExpression(storm::expressions::Expression e1) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return -e1;
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createTrueExpression() const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::createTrue();
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createFalseExpression() const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createDoubleLiteralExpression(double value, bool& pass) const {
+            // If we are not supposed to accept double expressions, we reject it by setting pass to false.
+            if (!this->allowDoubleLiteralsFlag) {
+                pass = false;
+            }
+            
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::createDoubleLiteral(value);
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createIntegerLiteralExpression(int value) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::createIntegerLiteral(static_cast<int_fast64_t>(value));
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::minimum(e1, e2);
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::maximum(e1, e2);
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createFloorExpression(storm::expressions::Expression e1) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1.floor();
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createCeilExpression(storm::expressions::Expression e1) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1.ceil();
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::getIdentifierExpression(std::string const& identifier) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                storm::expressions::Expression const* expression = this->identifiers_.find(identifier);
+                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Undeclared identifier '" << identifier << "'.");
+                return *expression;
+            }
+        }
+        
+        storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
+            this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+            return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, this->getFilename());
+        }
+        
+        storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
+            this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+            return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, this->getFilename());
+        }
+        
+        storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
+            this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+            return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, this->getFilename());
+        }
+        
+        storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
+            this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+            return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, expression, this->getFilename());
+        }
+        
+        storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
+            this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+            return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, expression, this->getFilename());
+        }
+        
+        storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
+            this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+            return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, expression, this->getFilename());
+        }
+        
+        storm::prism::Formula PrismParser::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
+            if (this->secondRun) {
+                this->identifiers_.add(formulaName, expression);
+            }
+            return storm::prism::Formula(formulaName, expression, this->getFilename());
+        }
+        
+        storm::prism::Label PrismParser::createLabel(std::string const& labelName, storm::expressions::Expression expression) const {
+            return storm::prism::Label(labelName, expression, this->getFilename());
+        }
+        
+        storm::prism::RewardModel PrismParser::createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const {
+            return storm::prism::RewardModel(rewardModelName, stateRewards, transitionRewards, this->getFilename());
+        }
+        
+        storm::prism::StateReward PrismParser::createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
+            return storm::prism::StateReward(statePredicateExpression, rewardValueExpression, this->getFilename());
+        }
+        
+        storm::prism::TransitionReward PrismParser::createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
+            return storm::prism::TransitionReward(actionName, statePredicateExpression, rewardValueExpression, this->getFilename());
+        }
+        
+        storm::prism::Assignment PrismParser::createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const {
+            return storm::prism::Assignment(variableName, assignedExpression, this->getFilename());
+        }
+        
+        storm::prism::Update PrismParser::createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const {
+            ++globalProgramInformation.currentUpdateIndex;
+            return storm::prism::Update(globalProgramInformation.currentUpdateIndex - 1, likelihoodExpression, assignments, this->getFilename());
+        }
+        
+        storm::prism::Command PrismParser::createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const {
+            ++globalProgramInformation.currentCommandIndex;
+            return storm::prism::Command(globalProgramInformation.currentCommandIndex - 1, actionName, guardExpression, updates, this->getFilename());
+        }
+        
+        storm::prism::BooleanVariable PrismParser::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const {
+            this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
+            return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename());
+        }
+        
+        storm::prism::IntegerVariable PrismParser::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const {
+            this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
+            return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename());
+        }
+        
+        storm::prism::Module PrismParser::createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const {
+            globalProgramInformation.moduleToIndexMap[moduleName] = globalProgramInformation.modules.size();
+            return storm::prism::Module(moduleName, booleanVariables, integerVariables, commands, this->getFilename());
+        }
+        
+        storm::prism::Module PrismParser::createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const {
+            // Check whether the module to rename actually exists.
+            auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
+            LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "No module named '" << oldModuleName << "' to rename.");
+            storm::prism::Module const& moduleToRename = globalProgramInformation.modules[moduleIndexPair->second];
+            
+            if (!this->secondRun) {
+                // Register all (renamed) variables for later use.
+                for (auto const& variable : moduleToRename.getBooleanVariables()) {
+                    auto const& renamingPair = renaming.find(variable.getName());
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
+                    this->identifiers_.add(renamingPair->second, storm::expressions::Expression::createBooleanVariable(renamingPair->second));
+                }
+                for (auto const& variable : moduleToRename.getIntegerVariables()) {
+                    auto const& renamingPair = renaming.find(variable.getName());
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
+                    this->identifiers_.add(renamingPair->second, storm::expressions::Expression::createIntegerVariable(renamingPair->second));
+                }
+                
+                // Return a dummy module in the first pass.
+                return storm::prism::Module();
+            } else {
+                // Add a mapping from the new module name to its (future) index.
+                globalProgramInformation.moduleToIndexMap[newModuleName] = globalProgramInformation.modules.size();
+                
+                // Create a mapping from identifiers to the expressions they need to be replaced with.
+                std::map<std::string, storm::expressions::Expression> expressionRenaming;
+                for (auto const& namePair : renaming) {
+                    storm::expressions::Expression const* substitutedExpression = this->identifiers_.find(namePair.second);
+                    // If the mapped-to-value is an expression, we need to replace it.
+                    if (substitutedExpression != nullptr) {
+                        expressionRenaming.emplace(namePair.first, *substitutedExpression);
+                    }
+                }
+                
+                // Rename the boolean variables.
+                std::vector<storm::prism::BooleanVariable> booleanVariables;
+                for (auto const& variable : moduleToRename.getBooleanVariables()) {
+                    auto const& renamingPair = renaming.find(variable.getName());
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
+                    
+                    booleanVariables.push_back(storm::prism::BooleanVariable(renamingPair->second, variable.getInitialValueExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1)));
+                }
+                
+                // Rename the integer variables.
+                std::vector<storm::prism::IntegerVariable> integerVariables;
+                for (auto const& variable : moduleToRename.getIntegerVariables()) {
+                    auto const& renamingPair = renaming.find(variable.getName());
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
+                    
+                    integerVariables.push_back(storm::prism::IntegerVariable(renamingPair->second, variable.getLowerBoundExpression().substitute<std::map>(expressionRenaming), variable.getUpperBoundExpression().substitute<std::map>(expressionRenaming), variable.getInitialValueExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1)));
+                }
+                
+                // Rename commands.
+                std::vector<storm::prism::Command> commands;
+                for (auto const& command : moduleToRename.getCommands()) {
+                    std::vector<storm::prism::Update> updates;
+                    for (auto const& update : command.getUpdates()) {
+                        std::vector<storm::prism::Assignment> assignments;
+                        for (auto const& assignment : update.getAssignments()) {
+                            auto const& renamingPair = renaming.find(assignment.getVariableName());
+                            if (renamingPair != renaming.end()) {
+                                assignments.emplace_back(renamingPair->second, assignment.getExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1));
+                            } else {
+                                assignments.emplace_back(assignment.getVariableName(), assignment.getExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1));
+                            }
+                        }
+                        updates.emplace_back(globalProgramInformation.currentUpdateIndex, update.getLikelihoodExpression().substitute<std::map>(expressionRenaming), assignments, this->getFilename(), get_line(qi::_1));
+                        ++globalProgramInformation.currentUpdateIndex;
+                    }
+                    
+                    std::string newActionName = command.getActionName();
+                    auto const& renamingPair = renaming.find(command.getActionName());
+                    if (renamingPair != renaming.end()) {
+                        newActionName = renamingPair->second;
+                    }
+                    
+                    commands.emplace_back(globalProgramInformation.currentCommandIndex, newActionName, command.getGuardExpression().substitute<std::map>(expressionRenaming), updates, this->getFilename(), get_line(qi::_1));
+                    ++globalProgramInformation.currentCommandIndex;
+                }
+                
+                return storm::prism::Module(newModuleName, booleanVariables, integerVariables, commands, this->getFilename());
+            }
+        }
+        
+        storm::prism::Program PrismParser::createProgram(GlobalProgramInformation const& globalProgramInformation) const {
+            return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, globalProgramInformation.hasInitialStatesExpression, globalProgramInformation.initialStatesExpression, globalProgramInformation.labels, this->getFilename());
+        }
+    } // namespace parser
+} // namespace storm
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
new file mode 100644
index 000000000..e271b2298
--- /dev/null
+++ b/src/parser/PrismParser.h
@@ -0,0 +1,320 @@
+#ifndef STORM_PARSER_PRISMPARSER_H_
+#define	STORM_PARSER_PRISMPARSER_H_
+
+// Include files for file input.
+#include <fstream>
+#include <memory>
+#include <iomanip>
+
+// Include boost spirit.
+#define BOOST_SPIRIT_USE_PHOENIX_V3
+#include <boost/typeof/typeof.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/spirit/include/support_line_pos_iterator.hpp>
+#include <boost/spirit/home/classic/iterator/position_iterator.hpp>
+
+namespace qi = boost::spirit::qi;
+namespace phoenix = boost::phoenix;
+
+typedef std::string::const_iterator BaseIteratorType;
+typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType;
+typedef PositionIteratorType Iterator;
+typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
+typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
+
+#include "src/storage/prism/Program.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/exceptions/ExceptionMacros.h"
+
+namespace storm {
+    namespace parser {
+        class GlobalProgramInformation {
+        public:
+            // Default construct the header information.
+            GlobalProgramInformation() = default;
+            
+            // Members for all essential information that needs to be collected.
+            storm::prism::Program::ModelType modelType;
+            std::vector<storm::prism::Constant> constants;
+            std::vector<storm::prism::Formula> formulas;
+            std::vector<storm::prism::BooleanVariable> globalBooleanVariables;
+            std::vector<storm::prism::IntegerVariable> globalIntegerVariables;
+            std::map<std::string, uint_fast64_t> moduleToIndexMap;
+            std::vector<storm::prism::Module> modules;
+            std::vector<storm::prism::RewardModel> rewardModels;
+            std::vector<storm::prism::Label> labels;
+            storm::expressions::Expression initialStatesExpression;
+            bool hasInitialStatesExpression;
+            
+            // Counters to provide unique indexing for commands and updates.
+            uint_fast64_t currentCommandIndex;
+            uint_fast64_t currentUpdateIndex;
+        };
+
+        class PrismParser : public qi::grammar<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> {
+        public:
+            /*!
+             * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
+             *
+             * @param filename the name of the file to parse.
+             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
+             * @return The resulting PRISM program.
+             */
+            static storm::prism::Program parse(std::string const& filename, bool typeCheck = true);
+            
+            /*!
+             * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
+             *
+             * @param input The input string to parse.
+             * @param filename The name of the file from which the input was read.
+             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
+             * @return The resulting PRISM program.
+             */
+            static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool typeCheck = true);
+            
+        private:
+            struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
+                modelTypeStruct() {
+                    add
+                    ("dtmc", storm::prism::Program::ModelType::DTMC)
+                    ("ctmc", storm::prism::Program::ModelType::CTMC)
+                    ("mdp", storm::prism::Program::ModelType::MDP)
+                    ("ctmdp", storm::prism::Program::ModelType::CTMDP)
+                    ("ma", storm::prism::Program::ModelType::MA);
+                }
+            };
+            
+            struct keywordsStruct : qi::symbols<char, bool> {
+                keywordsStruct() {
+                    add
+                    ("dtmc", 1)
+                    ("ctmc", 2)
+                    ("mdp", 3)
+                    ("ctmdp", 4)
+                    ("ma", 5)
+                    ("const", 6)
+                    ("int", 7)
+                    ("bool", 8)
+                    ("module", 9)
+                    ("endmodule", 10)
+                    ("rewards", 11)
+                    ("endrewards", 12)
+                    ("true", 13)
+                    ("min", 14)
+                    ("max", 15)
+                    ("floor", 16)
+                    ("ceil", 17)
+                    ("init", 18)
+                    ("endinit", 19);
+                }
+            };
+            
+            // Functor used for displaying error information.
+            struct ErrorHandler {
+                typedef qi::error_handler_result result_type;
+                
+                template<typename T1, typename T2, typename T3, typename T4>
+                qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
+                    //                    LOG4CPLUS_ERROR(logger, "Error: expecting " << what << " in line " << get_line(where) << " at column " << get_column(b, where, 4) << ".");
+                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << "." << std::endl;
+                    T3 end(where);
+                    while (end != e && *end != '\r' && *end != '\n') {
+                        ++end;
+                    }
+                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << ": \n" << std::string(get_line_start(b, where), end) << " ... \n" << std::setw(std::distance(b, where)) << '^' << "---- here\n";
+                    return qi::fail;
+                }
+            };
+            
+            // Functor used for annotating entities with line number information.
+            class PositionAnnotation {
+            public:
+                typedef void result_type;
+                
+                PositionAnnotation(Iterator first) : first(first) {
+                    // Intentionally left empty.
+                }
+                
+                template<typename Entity, typename First, typename Last>
+                result_type operator()(Entity& entity, First f, Last l) const {
+                    entity.setLineNumber(get_line(f));
+                }
+            private:
+                std::string filename;
+                Iterator const first;
+            };
+            
+            /*!
+             * Creates a grammar for the given filename and the iterator to the first input to parse.
+             *
+             * @param filename The filename that is to be read. This is used for proper error reporting.
+             * @param first The iterator to the beginning of the input.
+             */
+            PrismParser(std::string const& filename, Iterator first);
+            
+            /*!
+             * Sets an internal flag that indicates the second run is now taking place.
+             */
+            void moveToSecondRun();
+            
+            // A flag that stores whether the grammar is currently doing the second run.
+            bool secondRun;
+            
+            /*!
+             * Sets whether doubles literals are allowed in the parsed expression.
+             *
+             * @param flag Indicates whether to allow or forbid double literals in the parsed expression.
+             */
+            void allowDoubleLiterals(bool flag);
+            
+            // A flag that stores wether to allow or forbid double literals in parsed expressions.
+            bool allowDoubleLiteralsFlag;
+            
+            // The name of the file being parsed.
+            std::string filename;
+            
+            /*!
+             * Retrieves the name of the file currently being parsed.
+             *
+             * @return The name of the file currently being parsed.
+             */
+            std::string const& getFilename() const;
+            
+            // A function used for annotating the entities with their position.
+            phoenix::function<ErrorHandler> handler;
+            phoenix::function<PositionAnnotation> annotate;
+            
+            // The starting point of the grammar.
+            qi::rule<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
+            
+            // Rules for model type.
+            qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
+            
+            // Rules for parsing the program header.
+            qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedDoubleConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> definedConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> definedBooleanConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> definedIntegerConstantDefinition;
+            qi::rule<Iterator, storm::prism::Constant(), Skipper> definedDoubleConstantDefinition;
+            
+            // Rules for global variable definitions.
+            qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
+            qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalBooleanVariableDefinition;
+            qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalIntegerVariableDefinition;
+            
+            // Rules for modules definition.
+            qi::rule<Iterator, std::vector<storm::prism::Module>(GlobalProgramInformation&), Skipper> moduleDefinitionList;
+            qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::vector<storm::prism::BooleanVariable>, std::vector<storm::prism::IntegerVariable>>, Skipper> moduleDefinition;
+            qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
+            
+            // Rules for variable definitions.
+            qi::rule<Iterator, qi::unused_type(std::vector<storm::prism::BooleanVariable>&, std::vector<storm::prism::IntegerVariable>&), Skipper> variableDefinition;
+            qi::rule<Iterator, storm::prism::BooleanVariable(), Skipper> booleanVariableDefinition;
+            qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
+            
+            // Rules for command definitions.
+            qi::rule<Iterator, storm::prism::Command(GlobalProgramInformation&), qi::locals<std::string>, Skipper> commandDefinition;
+            qi::rule<Iterator, std::vector<storm::prism::Update>(GlobalProgramInformation&), Skipper> updateListDefinition;
+            qi::rule<Iterator, storm::prism::Update(GlobalProgramInformation&), Skipper> updateDefinition;
+            qi::rule<Iterator, std::vector<storm::prism::Assignment>(), Skipper> assignmentDefinitionList;
+            qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
+            
+            // Rules for reward definitions.
+            qi::rule<Iterator, storm::prism::RewardModel(), qi::locals<std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
+            qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
+            qi::rule<Iterator, storm::prism::TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
+            
+            // Rules for initial states expression.
+            qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> initialStatesConstruct;
+            
+            // Rules for label definitions.
+            qi::rule<Iterator, storm::prism::Label(), Skipper> labelDefinition;
+            
+            // Rules for formula definitions.
+            qi::rule<Iterator, storm::prism::Formula(), Skipper> formulaDefinition;
+            
+            // Rules for identifier parsing.
+            qi::rule<Iterator, std::string(), Skipper> identifier;
+            
+            // Rules for parsing a composed expression.
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> iteExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> orExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> identifierExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
+            
+            // Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
+            boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
+            
+            // Parsers that recognize special keywords and model types.
+            storm::parser::PrismParser::keywordsStruct keywords_;
+            storm::parser::PrismParser::modelTypeStruct modelType_;
+            qi::symbols<char, storm::expressions::Expression> identifiers_;
+            
+            // Helper methods used in the grammar.
+            bool isValidIdentifier(std::string const& identifier);
+            bool addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
+            
+            storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const;
+            storm::expressions::Expression createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createNotExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression createTrueExpression() const;
+            storm::expressions::Expression createFalseExpression() const;
+            storm::expressions::Expression createDoubleLiteralExpression(double value, bool& pass) const;
+            storm::expressions::Expression createIntegerLiteralExpression(int value) const;
+            storm::expressions::Expression createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createFloorExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression createCeilExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression getIdentifierExpression(std::string const& identifier) const;
+            
+            storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
+            storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
+            storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
+            storm::prism::Constant createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
+            storm::prism::Constant createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
+            storm::prism::Constant createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
+            storm::prism::Formula createFormula(std::string const& formulaName, storm::expressions::Expression expression) const;
+            storm::prism::Label createLabel(std::string const& labelName, storm::expressions::Expression expression) const;
+            storm::prism::RewardModel createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const;
+            storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
+            storm::prism::TransitionReward createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
+            storm::prism::Assignment createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const;
+            storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const;
+            storm::prism::Command createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const;
+            storm::prism::BooleanVariable createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const;
+            storm::prism::IntegerVariable createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const;
+            storm::prism::Module createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const;
+            storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const;
+            storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation) const;
+        };
+    } // namespace parser
+} // namespace storm
+
+#endif	/* STORM_PARSER_PRISMPARSER_H_ */
+
diff --git a/src/parser/prismparser/PrismGrammar.cpp b/src/parser/prismparser/PrismGrammar.cpp
deleted file mode 100644
index b8c06daa9..000000000
--- a/src/parser/prismparser/PrismGrammar.cpp
+++ /dev/null
@@ -1,373 +0,0 @@
-// #define BOOST_SPIRIT_DEBUG
-#include "src/parser/prismparser/PrismGrammar.h"
-#include "src/exceptions/InvalidArgumentException.h"
-#include "src/exceptions/WrongFormatException.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            PrismGrammar::PrismGrammar(std::string const& filename, Iterator first) : PrismGrammar::base_type(start), doExpressionGeneration(false), filename(filename), annotate(first) {
-                // Parse simple identifier.
-                identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&PrismGrammar::isValidIdentifier, phoenix::ref(*this), qi::_1)];
-                identifier.name("identifier");
-                
-                setExpressionGeneration(doExpressionGeneration);
-                
-                modelTypeDefinition %= modelType_;
-                modelTypeDefinition.name("model type");
-
-                undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedBooleanConstant, phoenix::ref(*this), qi::_1)];
-                undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
-
-                undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedIntegerConstant, phoenix::ref(*this), qi::_1)];
-                undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
-                
-                undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedDoubleConstant, phoenix::ref(*this), qi::_1)];
-                undefinedDoubleConstantDefinition.name("undefined double constant definition");
-
-                undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition);
-                undefinedConstantDefinition.name("undefined constant definition");
-
-                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)];
-                definedBooleanConstantDefinition.name("defined boolean constant declaration");
-
-                definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)];
-                definedIntegerConstantDefinition.name("defined integer constant declaration");
-
-                definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)];
-                definedDoubleConstantDefinition.name("defined double constant declaration");
-                
-                definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
-                definedConstantDefinition.name("defined constant definition");
-                
-                formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createFormula, phoenix::ref(*this), qi::_1, qi::_2)];
-                formulaDefinition.name("formula definition");
-                
-                booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)];
-                booleanVariableDefinition.name("boolean variable definition");
-                
-                integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismGrammar::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression[qi::_a = qi::_1] > qi::lit("..") > expression > qi::lit("]")[phoenix::bind(&PrismGrammar::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)];
-                integerVariableDefinition.name("integer variable definition");
-                
-                variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]);
-                variableDefinition.name("variable declaration");
-                
-                globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)]));
-                globalVariableDefinition.name("global variable declaration list");
-                
-                programHeader = modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
-                                    >   *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)] | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)])
-                                    >   *(formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1)])
-                                    >   *(globalVariableDefinition(qi::_r1));
-                programHeader.name("program header");
-                
-                stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
-                stateRewardDefinition.name("state reward definition");
-                
-                transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
-                transitionRewardDefinition.name("transition reward definition");
-
-                rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"")
-                                         > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)]
-                                             |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
-                                             )
-                                         >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismGrammar::createRewardModel, phoenix::ref(*this), qi::_1, qi::_a, qi::_b)];
-                rewardModelDefinition.name("reward model definition");
-                
-                initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismGrammar::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)];
-                initialStatesConstruct.name("initial construct");
-                
-                labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
-                labelDefinition.name("label definition");
-
-                assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&PrismGrammar::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)];
-                assignmentDefinition.name("assignment");
-                
-                assignmentDefinitionList %= +assignmentDefinition % "&";
-                assignmentDefinitionList.name("assignment list");
-
-                updateDefinition = (((plusExpression > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)];
-                updateDefinition.name("update");
-                
-                updateListDefinition %= +updateDefinition(qi::_r1) % "+";
-                updateListDefinition.name("update list");
-                
-                commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)];
-                commandDefinition.name("command definition");
-
-                moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition(qi::_r1) > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createModule, phoenix::ref(*this), qi::_1, qi::_a, qi::_b, qi::_2, qi::_r1)];
-                moduleDefinition.name("module definition");
-                
-                moduleRenaming = ((qi::lit("module") >> identifier >> qi::lit("=")) > identifier > qi::lit("[")
-                                  > ((identifier > qi::lit("=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))] % ",") > qi::lit("]")
-                                  > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createRenamedModule, phoenix::ref(*this), qi::_1, qi::_2, qi::_a, qi::_r1)];
-                moduleRenaming.name("module definition via renaming");
-                
-                moduleDefinitionList %= +(moduleRenaming(qi::_r1) | moduleDefinition(qi::_r1))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_r1), qi::_1)];
-                moduleDefinitionList.name("module list");
-
-                start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(initialStatesConstruct(qi::_a) | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)]) > qi::eoi)[qi::_val = phoenix::bind(&PrismGrammar::createProgram, phoenix::ref(*this), qi::_a)];
-                start.name("probabilistic program");
-
-                // Enable location tracking for important entities.
-                auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
-                qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction);
-                qi::on_success(undefinedIntegerConstantDefinition, setLocationInfoFunction);
-                qi::on_success(undefinedDoubleConstantDefinition, setLocationInfoFunction);
-                qi::on_success(definedBooleanConstantDefinition, setLocationInfoFunction);
-                qi::on_success(definedIntegerConstantDefinition, setLocationInfoFunction);
-                qi::on_success(definedDoubleConstantDefinition, setLocationInfoFunction);
-                qi::on_success(booleanVariableDefinition, setLocationInfoFunction);
-                qi::on_success(integerVariableDefinition, setLocationInfoFunction);
-                qi::on_success(moduleDefinition, setLocationInfoFunction);
-                qi::on_success(moduleRenaming, setLocationInfoFunction);
-                qi::on_success(formulaDefinition, setLocationInfoFunction);
-                qi::on_success(rewardModelDefinition, setLocationInfoFunction);
-                qi::on_success(labelDefinition, setLocationInfoFunction);
-                qi::on_success(commandDefinition, setLocationInfoFunction);
-                qi::on_success(updateDefinition, setLocationInfoFunction);
-                qi::on_success(assignmentDefinition, setLocationInfoFunction);
-            }
-            
-            void PrismGrammar::setExpressionGeneration(bool doExpressionGeneration) {
-                if (doExpressionGeneration) {
-                    floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]];
-                    floorCeilExpression.name("floor/ceil expression");
-                    
-                    minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]];
-                    minMaxExpression.name("min/max expression");
-                    
-                    identifierExpression = identifier[qi::_val = phoenix::bind(&PrismGrammar::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
-                    identifierExpression.name("identifier expression");
-                    
-                    literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | strict_double[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleLiteral, qi::_1)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)];
-                    literalExpression.name("literal expression");
-                    
-                    atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression;
-                    atomicExpression.name("atomic expression");
-                    
-                    unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = !qi::_1] | (qi::lit("-") >> atomicExpression)[qi::_val = -qi::_1];
-                    unaryExpression.name("unary expression");
-                    
-                    multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = qi::_val * qi::_1] .else_ [qi::_val = qi::_val / qi::_1]]);
-                    multiplicationExpression.name("multiplication expression");
-                    
-                    plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = qi::_val + qi::_1] .else_ [qi::_val = qi::_val - qi::_1]];
-                    plusExpression.name("plus expression");
-                    
-                    relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = qi::_1 >= qi::_1] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = qi::_1 > qi::_2] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = qi::_1 <= qi::_2] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = qi::_1 < qi::_2] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = qi::_1 == qi::_2] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = qi::_1 != qi::_2] | plusExpression[qi::_val = qi::_1];
-                    relativeExpression.name("relative expression");
-                    
-                    andExpression = relativeExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> relativeExpression)[qi::_val = qi::_val && qi::_1];
-                    andExpression.name("and expression");
-                    
-                    orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = qi::_val || qi::_1];
-                    orExpression.name("or expression");
-                    
-                    expression %= orExpression;
-                    expression.name("expression");
-                } else {
-                    floorCeilExpression = ((qi::lit("floor") | qi::lit("ceil")) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    floorCeilExpression.name("floor/ceil expression");
-                    
-                    minMaxExpression = ((qi::lit("min") | qi::lit("max")) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    minMaxExpression.name("min/max expression");
-                    
-                    identifierExpression = identifier[qi::_val = phoenix::construct<storm::expressions::Expression>(), qi::_pass = phoenix::bind(&PrismGrammar::isValidIdentifier, phoenix::ref(*this), qi::_1)];
-                    identifierExpression.name("identifier expression");
-                    
-                    literalExpression = (qi::lit("true") | qi::lit("false") | strict_double | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    literalExpression.name("literal expression");
-                    
-                    atomicExpression = (minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    atomicExpression.name("atomic expression");
-                    
-                    unaryExpression = (atomicExpression | (qi::lit("!") >> atomicExpression) | (qi::lit("-") >> atomicExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    unaryExpression.name("unary expression");
-                    
-                    multiplicationExpression = (unaryExpression >> *((qi::lit("*") | qi::lit("/")) >> unaryExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    multiplicationExpression.name("multiplication expression");
-                    
-                    plusExpression = (multiplicationExpression >> *((qi::lit("+") | qi::lit("-")) >> multiplicationExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    plusExpression.name("plus expression");
-                    
-                    relativeExpression = ((plusExpression >> qi::lit(">=") >> plusExpression) | (plusExpression >> qi::lit(">") >> plusExpression) | (plusExpression >> qi::lit("<=") >> plusExpression) | (plusExpression >> qi::lit("<") >> plusExpression) | (plusExpression >> qi::lit("=") >> plusExpression) | (plusExpression >> qi::lit("!=") >> plusExpression) | plusExpression)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    relativeExpression.name("relative expression");
-                    
-                    andExpression = (relativeExpression >> *(qi::lit("&") >> relativeExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    andExpression.name("and expression");
-                    
-                    orExpression = (andExpression >> *(qi::lit("|") >> andExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                    orExpression.name("or expression");
-                    
-                    expression %= orExpression;
-                    expression.name("expression");
-                }
-                
-                // Enable error reporting.
-                qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-                
-                // Finally toggle the internal flag.
-                this->doExpressionGeneration = doExpressionGeneration;
-            }
-            
-            void PrismGrammar::toggleExpressionGeneration() {
-                setExpressionGeneration(!doExpressionGeneration);
-            }
-            
-            void PrismGrammar::allowDoubleLiterals(bool flag) {
-                if (flag) {
-                    if (this->doExpressionGeneration) {
-                        literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | strict_double[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleLiteral, qi::_1)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)];
-                        literalExpression.name("literal expression");
-                    } else {
-                        literalExpression = (qi::lit("true") | qi::lit("false") | strict_double | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                        literalExpression.name("literal expression");
-                    }
-                } else {
-                    if (this->doExpressionGeneration) {
-                        literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)];
-                        literalExpression.name("literal expression");
-                    } else {
-                        literalExpression = (qi::lit("true") | qi::lit("false") | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)];
-                        literalExpression.name("literal expression");
-                    }
-                }
-            }
-            
-            std::string const& PrismGrammar::getFilename() const {
-                return this->filename;
-            }
-            
-            bool PrismGrammar::isValidIdentifier(std::string const& identifier) {
-                if (this->keywords_.find(identifier) != nullptr) {
-                    return false;
-                }
-                return true;
-            }
-            
-            bool PrismGrammar::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
-                LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::InvalidArgumentException, "Program must not define two initial constructs.");
-                if (globalProgramInformation.hasInitialStatesExpression) {
-                    return false;
-                }
-                globalProgramInformation.hasInitialStatesExpression = true;
-                globalProgramInformation.initialStatesExpression = initialStatesExpression;
-                return true;
-            }
-            
-            storm::expressions::Expression PrismGrammar::getIdentifierExpression(std::string const& identifier) const {
-                storm::expressions::Expression const* expression = this->identifiers_.find(identifier);
-                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Undeclared identifier '" << identifier << "'.");
-                return *expression;
-            }
-            
-            storm::prism::Constant PrismGrammar::createUndefinedBooleanConstant(std::string const& newConstant) const {
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
-                return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, this->getFilename());
-            }
-            
-            storm::prism::Constant PrismGrammar::createUndefinedIntegerConstant(std::string const& newConstant) const {
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
-                return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, this->getFilename());
-            }
-            
-            storm::prism::Constant PrismGrammar::createUndefinedDoubleConstant(std::string const& newConstant) const {
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
-                return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, this->getFilename());
-            }
-            
-            storm::prism::Constant PrismGrammar::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
-                return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, expression, this->getFilename());
-            }
-            
-            storm::prism::Constant PrismGrammar::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
-                return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, expression, this->getFilename());
-            }
-            
-            storm::prism::Constant PrismGrammar::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
-                return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, expression, this->getFilename());
-            }
-            
-            storm::prism::Formula PrismGrammar::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
-                this->identifiers_.add(formulaName, expression);
-                return storm::prism::Formula(formulaName, expression, this->getFilename());
-            }
-            
-            storm::prism::Label PrismGrammar::createLabel(std::string const& labelName, storm::expressions::Expression expression) const {
-                return storm::prism::Label(labelName, expression, this->getFilename());
-            }
-            
-            storm::prism::RewardModel PrismGrammar::createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const {
-                return storm::prism::RewardModel(rewardModelName, stateRewards, transitionRewards, this->getFilename());
-            }
-            
-            storm::prism::StateReward PrismGrammar::createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
-                return storm::prism::StateReward(statePredicateExpression, rewardValueExpression, this->getFilename());
-            }
-            
-            storm::prism::TransitionReward PrismGrammar::createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
-                return storm::prism::TransitionReward(actionName, statePredicateExpression, rewardValueExpression, this->getFilename());
-            }
-            
-            storm::prism::Assignment PrismGrammar::createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const {
-                return storm::prism::Assignment(variableName, assignedExpression, this->getFilename());
-            }
-            
-            storm::prism::Update PrismGrammar::createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const {
-                ++globalProgramInformation.currentUpdateIndex;
-                return storm::prism::Update(globalProgramInformation.currentUpdateIndex - 1, likelihoodExpression, assignments, this->getFilename());
-            }
-            
-            storm::prism::Command PrismGrammar::createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const {
-                ++globalProgramInformation.currentCommandIndex;
-                return storm::prism::Command(globalProgramInformation.currentCommandIndex - 1, actionName, guardExpression, updates, this->getFilename());
-            }
-            
-            storm::prism::BooleanVariable PrismGrammar::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const {
-                this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
-                return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename());
-            }
-            
-            storm::prism::IntegerVariable PrismGrammar::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const {
-                this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
-                return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename());
-            }
-            
-            storm::prism::Module PrismGrammar::createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const {
-                globalProgramInformation.moduleToIndexMap[moduleName] = globalProgramInformation.modules.size();
-                return storm::prism::Module(moduleName, booleanVariables, integerVariables, commands, this->getFilename());
-            }
-            
-            storm::prism::Module PrismGrammar::createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const {
-                auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
-                LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "No module named '" << oldModuleName << "' to rename.");
-                globalProgramInformation.moduleToIndexMap[newModuleName] = globalProgramInformation.modules.size();
-                uint_fast64_t commandBaseIndex = globalProgramInformation.currentCommandIndex;
-                uint_fast64_t updateBaseIndex = globalProgramInformation.currentUpdateIndex;
-                storm::prism::Module const& moduleToClone = globalProgramInformation.modules[moduleIndexPair->second];
-                globalProgramInformation.currentCommandIndex += moduleToClone.getNumberOfCommands();
-                globalProgramInformation.currentUpdateIndex += moduleToClone.getNumberOfUpdates();
-                return storm::prism::Module(moduleToClone, newModuleName, commandBaseIndex, updateBaseIndex, renaming, this->getFilename());
-            }
-            
-            storm::prism::Program PrismGrammar::createProgram(GlobalProgramInformation const& globalProgramInformation) const {
-                return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, globalProgramInformation.hasInitialStatesExpression, globalProgramInformation.initialStatesExpression, globalProgramInformation.labels, this->getFilename());
-            }
-        } // namespace prism
-    } // namespace parser
-} // namespace storm
diff --git a/src/parser/prismparser/PrismGrammar.h b/src/parser/prismparser/PrismGrammar.h
deleted file mode 100644
index 29d0afb96..000000000
--- a/src/parser/prismparser/PrismGrammar.h
+++ /dev/null
@@ -1,282 +0,0 @@
-#ifndef STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H_
-#define	STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H_
-
-// Include files for file input.
-#include <istream>
-#include <memory>
-#include <iomanip>
-
-// Include boost spirit.
-#define BOOST_SPIRIT_USE_PHOENIX_V3
-#include <boost/typeof/typeof.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
-#include <boost/spirit/include/support_line_pos_iterator.hpp>
-#include <boost/spirit/home/classic/iterator/position_iterator.hpp>
-
-namespace qi = boost::spirit::qi;
-namespace phoenix = boost::phoenix;
-
-typedef std::string::const_iterator BaseIteratorType;
-typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType;
-typedef PositionIteratorType Iterator;
-typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
-typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
-
-#include "src/storage/prism/Program.h"
-#include "src/storage/expressions/Expression.h"
-#include "src/exceptions/ExceptionMacros.h"
-
-namespace storm {
-    namespace parser {
-        namespace prism {
-            struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
-                modelTypeStruct() {
-                    add
-                    ("dtmc", storm::prism::Program::ModelType::DTMC)
-                    ("ctmc", storm::prism::Program::ModelType::CTMC)
-                    ("mdp", storm::prism::Program::ModelType::MDP)
-                    ("ctmdp", storm::prism::Program::ModelType::CTMDP)
-                    ("ma", storm::prism::Program::ModelType::MA);
-                }
-            };
-            
-            struct keywordsStruct : qi::symbols<char, bool> {
-                keywordsStruct() {
-                    add
-                    ("dtmc", 1)
-                    ("ctmc", 2)
-                    ("mdp", 3)
-                    ("ctmdp", 4)
-                    ("ma", 5)
-                    ("const", 6)
-                    ("int", 7)
-                    ("bool", 8)
-                    ("module", 9)
-                    ("endmodule", 10)
-                    ("rewards", 11)
-                    ("endrewards", 12)
-                    ("true", 13)
-                    ("min", 14)
-                    ("max", 15)
-                    ("floor", 16)
-                    ("ceil", 17)
-                    ("init", 18)
-                    ("endinit", 19);
-                }
-            };
-            
-            class GlobalProgramInformation {
-            public:
-                // Default construct the header information.
-                GlobalProgramInformation() = default;
-                
-                // Members for all essential information that needs to be collected.
-                storm::prism::Program::ModelType modelType;
-                std::vector<storm::prism::Constant> constants;
-                std::vector<storm::prism::Formula> formulas;
-                std::vector<storm::prism::BooleanVariable> globalBooleanVariables;
-                std::vector<storm::prism::IntegerVariable> globalIntegerVariables;
-                std::map<std::string, uint_fast64_t> moduleToIndexMap;
-                std::vector<storm::prism::Module> modules;
-                std::vector<storm::prism::RewardModel> rewardModels;
-                std::vector<storm::prism::Label> labels;
-                storm::expressions::Expression initialStatesExpression;
-                bool hasInitialStatesExpression;
-                
-                // Counters to provide unique indexing for commands and updates.
-                uint_fast64_t currentCommandIndex;
-                uint_fast64_t currentUpdateIndex;
-            };
-            
-            // Functor used for displaying error information.
-            struct ErrorHandler {
-                typedef qi::error_handler_result result_type;
-                
-                template<typename T1, typename T2, typename T3, typename T4>
-                qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
-//                    LOG4CPLUS_ERROR(logger, "Error: expecting " << what << " in line " << get_line(where) << " at column " << get_column(b, where, 4) << ".");
-                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << "." << std::endl;
-                    T3 end(where);
-                    while (end != e && *end != '\r' && *end != '\n') {
-                        ++end;
-                    }
-                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << ": \n" << std::string(get_line_start(b, where), end) << " ... \n" << std::setw(std::distance(b, where)) << '^' << "---- here\n";
-                    return qi::fail;
-                }
-            };
-            
-            // Functor used for annotating entities with line number information.
-            class PositionAnnotation {
-            public:
-                typedef void result_type;
-                
-                PositionAnnotation(Iterator first) : first(first) {
-                    // Intentionally left empty.
-                }
-
-                template<typename Entity, typename First, typename Last>
-                result_type operator()(Entity& entity, First f, Last l) const {
-                    entity.setLineNumber(get_line(f));
-                }
-            private:
-                std::string filename;
-                Iterator const first;
-            };
-            
-            class PrismGrammar : public qi::grammar<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> {
-            public:
-                /*!
-                 * Creates a grammar for the given filename and the iterator to the first input to parse.
-                 *
-                 * @param filename The filename that is to be read. This is used for proper error reporting.
-                 * @param first The iterator to the beginning of the input.
-                 */
-                PrismGrammar(std::string const& filename, Iterator first);
-
-                /*!
-                 * Toggles whether or not expressions are generated.
-                 */
-                void toggleExpressionGeneration();
-                
-            private:
-                // A flag that stores whether the grammar currently generates expressions or not.
-                bool doExpressionGeneration;
-                
-                /*!
-                 * Sets the expression generation to the desired value.
-                 *
-                 * @param doExpressionGeneration A flag that sets whether or not expressions are generated.
-                 */
-                void setExpressionGeneration(bool doExpressionGeneration);
-                
-                /*!
-                 * Sets whether doubles literals are allowed in the parsed expression.
-                 *
-                 * @param flag Indicates whether to allow or forbid double literals in the parsed expression.
-                 */
-                void allowDoubleLiterals(bool flag);
-                
-                // The name of the file being parsed.
-                std::string filename;
-
-                /*!
-                 * Retrieves the name of the file currently being parsed.
-                 *
-                 * @return The name of the file currently being parsed.
-                 */
-                std::string const& getFilename() const;
-                
-                // A function used for annotating the entities with their position.
-                phoenix::function<ErrorHandler> handler;
-                phoenix::function<PositionAnnotation> annotate;
-                
-                // The starting point of the grammar.
-                qi::rule<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
-                
-                // Rules for model type.
-                qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
-                
-                // Rules for parsing the program header.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedDoubleConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedBooleanConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedIntegerConstantDefinition;
-                qi::rule<Iterator, storm::prism::Constant(), Skipper> definedDoubleConstantDefinition;
-                
-                // Rules for global variable definitions.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalBooleanVariableDefinition;
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalIntegerVariableDefinition;
-                
-                // Rules for modules definition.
-                qi::rule<Iterator, std::vector<storm::prism::Module>(GlobalProgramInformation&), Skipper> moduleDefinitionList;
-                qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::vector<storm::prism::BooleanVariable>, std::vector<storm::prism::IntegerVariable>>, Skipper> moduleDefinition;
-                qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
-                
-                // Rules for variable definitions.
-                qi::rule<Iterator, qi::unused_type(std::vector<storm::prism::BooleanVariable>&, std::vector<storm::prism::IntegerVariable>&), Skipper> variableDefinition;
-                qi::rule<Iterator, storm::prism::BooleanVariable(), Skipper> booleanVariableDefinition;
-                qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
-                
-                // Rules for command definitions.
-                qi::rule<Iterator, storm::prism::Command(GlobalProgramInformation&), qi::locals<std::string>, Skipper> commandDefinition;
-                qi::rule<Iterator, std::vector<storm::prism::Update>(GlobalProgramInformation&), Skipper> updateListDefinition;
-                qi::rule<Iterator, storm::prism::Update(GlobalProgramInformation&), Skipper> updateDefinition;
-                qi::rule<Iterator, std::vector<storm::prism::Assignment>(), Skipper> assignmentDefinitionList;
-                qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
-                
-                // Rules for reward definitions.
-                qi::rule<Iterator, storm::prism::RewardModel(), qi::locals<std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
-                qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
-                qi::rule<Iterator, storm::prism::TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
-                
-                // Rules for initial states expression.
-                qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> initialStatesConstruct;
-                
-                // Rules for label definitions.
-                qi::rule<Iterator, storm::prism::Label(), Skipper> labelDefinition;
-                
-                // Rules for formula definitions.
-                qi::rule<Iterator, storm::prism::Formula(), Skipper> formulaDefinition;
-                
-                // Rules for identifier parsing.
-                qi::rule<Iterator, std::string(), Skipper> identifier;
-                
-                // Rules for parsing a composed expression.
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> orExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), Skipper> identifierExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
-                qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
-                
-                // Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
-                boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
-                
-                // Parsers that recognize special keywords and model types.
-                storm::parser::prism::keywordsStruct keywords_;
-                storm::parser::prism::modelTypeStruct modelType_;
-                qi::symbols<char, storm::expressions::Expression> identifiers_;
-                
-                // Helper methods used in the grammar.
-                bool isValidIdentifier(std::string const& identifier);
-                bool addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
-                storm::expressions::Expression getIdentifierExpression(std::string const& identifier) const;
-                storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
-                storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
-                storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
-                storm::prism::Constant createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
-                storm::prism::Constant createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
-                storm::prism::Constant createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
-                storm::prism::Formula createFormula(std::string const& formulaName, storm::expressions::Expression expression) const;
-                storm::prism::Label createLabel(std::string const& labelName, storm::expressions::Expression expression) const;
-                storm::prism::RewardModel createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const;
-                storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
-                storm::prism::TransitionReward createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
-                storm::prism::Assignment createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const;
-                storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const;
-                storm::prism::Command createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const;
-                storm::prism::BooleanVariable createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const;
-                storm::prism::IntegerVariable createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const;
-                storm::prism::Module createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const;
-                storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const;
-                storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation) const;
-            };
-        } // namespace prism
-    } // namespace parser
-} // namespace storm
-
-
-#endif	/* STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H_ */
-
diff --git a/src/parser/prismparser/PrismParser.cpp b/src/parser/prismparser/PrismParser.cpp
deleted file mode 100644
index a261ba8cc..000000000
--- a/src/parser/prismparser/PrismParser.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "src/parser/prismparser/PrismParser.h"
-#include "src/parser/prismparser/PrismGrammar.h"
-
-// If the parser fails due to ill-formed data, this exception is thrown.
-#include "src/exceptions/ExceptionMacros.h"
-#include "src/exceptions/WrongFormatException.h"
-
-// Needed for file IO.
-#include <fstream>
-#include <iomanip>
-#include <limits>
-
-namespace storm {
-    namespace parser {
-        storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) {
-            // Open file and initialize result.
-            std::ifstream inputFileStream(filename, std::ios::in);
-            LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file " << filename << ".");
-            
-            storm::prism::Program result;
-            
-            // Now try to parse the contents of the file.
-            try {
-                std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
-                result = parseFromString(fileContent, filename, typeCheck);
-            } catch(std::exception& e) {
-                // In case of an exception properly close the file before passing exception.
-                inputFileStream.close();
-                throw e;
-            }
-            
-            // Close the stream in case everything went smoothly and return result.
-            inputFileStream.close();
-            return result;
-        }
-        
-        storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool typeCheck) {
-            PositionIteratorType first(input.begin());
-            PositionIteratorType iter = first;
-            PositionIteratorType last(input.end());
-            
-            // Create empty result;
-            storm::prism::Program result;
-            
-            // Create grammar.
-            storm::parser::prism::PrismGrammar grammar(filename, first);
-            try {
-                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
-                bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
-                LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in first pass.");
-                if (typeCheck) {
-                    first = PositionIteratorType(input.begin());
-                    iter = first;
-                    last = PositionIteratorType(input.end());
-                    grammar.toggleExpressionGeneration();
-                    succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
-                    LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in second pass.");
-                }
-            } catch (qi::expectation_failure<PositionIteratorType> const& e) {
-                // If the parser expected content different than the one provided, display information about the location of the error.
-                std::size_t lineNumber = boost::spirit::get_line(e.first);
-                
-                // Now propagate exception.
-                LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << ".");
-            }
-            
-            return result;
-        }
-    } // namespace parser
-} // namespace storm
diff --git a/src/parser/prismparser/PrismParser.h b/src/parser/prismparser/PrismParser.h
deleted file mode 100644
index 35d2404a6..000000000
--- a/src/parser/prismparser/PrismParser.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef STORM_PARSER_PRISMPARSER_H_
-#define STORM_PARSER_PRISMPARSER_H_
-
-// All classes of the intermediate representation are used.
-#include "src/storage/prism/Program.h"
-
-// Used for file input.
-#include <istream>
-
-namespace storm {
-    namespace parser {
-        class PrismParser {
-        public:
-            /*!
-             * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
-             *
-             * @param filename the name of the file to parse.
-             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
-             * @return The resulting PRISM program.
-             */
-            static storm::prism::Program parse(std::string const& filename, bool typeCheck = true);
-            
-            /*!
-             * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
-             *
-             * @param input The input string to parse.
-             * @param filename The name of the file from which the input was read.
-             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
-             * @return The resulting PRISM program.
-             */
-            static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool typeCheck = true);
-        };
-    } // namespace parser
-} // namespace storm
-
-#endif /* STORM_PARSER_PRISMPARSER_H_ */
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index 200b8ac0f..f66cd7dc3 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -52,6 +52,11 @@ namespace storm {
             return this->shared_from_this();
         }
         
+        std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue) {
+            stream << static_cast<std::underlying_type<ExpressionReturnType>::type>(enumValue);
+            return stream;
+        }
+        
         std::ostream& operator<<(std::ostream& stream, BaseExpression const& expression) {
             expression.printToStream(stream);
             return stream;
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 7ca9e63ad..4039209d3 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -17,6 +17,8 @@ namespace storm {
          */
         enum class ExpressionReturnType {Undefined, Bool, Int, Double};
         
+        std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue);
+        
         /*!
          * The base class of all expression classes.
          */
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index d72a683ac..7da4f8b37 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -7,6 +7,7 @@
 #include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/ExceptionMacros.h"
 
+#include "src/storage/expressions/IfThenElseExpression.h"
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/BinaryRelationExpression.h"
@@ -220,6 +221,12 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(lhs.getReturnType() == ExpressionReturnType::Int && rhs.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, lhs.getBaseExpressionPointer(), rhs.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Max)));
         }
         
+        Expression Expression::ite(Expression const& thenExpression, Expression const& elseExpression) {
+            LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Condition of if-then-else operator must be of boolean type.");
+            LOG_THROW(thenExpression.hasBooleanReturnType() && elseExpression.hasBooleanReturnType() || thenExpression.hasNumericalReturnType() && elseExpression.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "'then' and 'else' expression of if-then-else operator must have equal return type.");
+            return Expression(std::shared_ptr<BaseExpression>(new IfThenElseExpression(thenExpression.hasBooleanReturnType() && elseExpression.hasBooleanReturnType() ? ExpressionReturnType::Bool : (thenExpression.getReturnType() == ExpressionReturnType::Int && elseExpression.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double), this->getBaseExpressionPointer(), thenExpression.getBaseExpressionPointer(), elseExpression.getBaseExpressionPointer())));
+        }
+        
         Expression Expression::implies(Expression const& other) const {
             LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '&&' requires boolean operands.");
             return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Implies)));
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 47ca6d721..96f8ce6fd 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -54,6 +54,7 @@ namespace storm {
             Expression operator<(Expression const& other) const;
             Expression operator<=(Expression const& other) const;
             
+            Expression ite(Expression const& thenExpression, Expression const& elseExpression);
             Expression implies(Expression const& other) const;
             Expression iff(Expression const& other) const;
             
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index 8e6dca24e..928e6297c 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -4,6 +4,7 @@
 namespace storm {
     namespace expressions {
         // Forward-declare all expression classes.
+        class IfThenElseExpression;
         class BinaryBooleanFunctionExpression;
         class BinaryNumericalFunctionExpression;
         class BinaryRelationExpression;
@@ -20,6 +21,7 @@ namespace storm {
         
         class ExpressionVisitor {
         public:
+            virtual void visit(IfThenElseExpression const* expression) = 0;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0;
             virtual void visit(BinaryRelationExpression const* expression) = 0;
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
index e753583f9..17161775a 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
@@ -3,6 +3,7 @@
 
 #include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
 
+#include "src/storage/expressions/IfThenElseExpression.h"
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/BinaryRelationExpression.h"
@@ -29,6 +30,28 @@ namespace storm {
             return Expression(this->expressionStack.top());
         }
         
+        template<template<typename... Arguments> class MapType>
+        void IdentifierSubstitutionVisitor<MapType>::visit(IfThenElseExpression const* expression) {
+            expression->getCondition()->accept(this);
+            std::shared_ptr<BaseExpression const> conditionExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getThenExpression()->accept(this);
+            std::shared_ptr<BaseExpression const> thenExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getElseExpression()->accept(this);
+            std::shared_ptr<BaseExpression const> elseExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            // If the arguments did not change, we simply push the expression itself.
+            if (conditionExpression.get() == expression->getCondition().get() && thenExpression.get() == expression->getThenExpression().get() && elseExpression.get() == expression->getElseExpression().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new IfThenElseExpression(expression->getReturnType(), conditionExpression, thenExpression, elseExpression)));
+            }
+        }
+        
         template<template<typename... Arguments> class MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
             expression->getFirstOperand()->accept(this);
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.h b/src/storage/expressions/IdentifierSubstitutionVisitor.h
index 87976122c..6be7aa9ca 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.h
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.h
@@ -28,6 +28,7 @@ namespace storm {
              */
             Expression substitute(BaseExpression const* expression);
             
+            virtual void visit(IfThenElseExpression const* expression) override;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
             virtual void visit(BinaryRelationExpression const* expression) override;
diff --git a/src/storage/expressions/IfThenElseExpression.cpp b/src/storage/expressions/IfThenElseExpression.cpp
new file mode 100644
index 000000000..dffee088d
--- /dev/null
+++ b/src/storage/expressions/IfThenElseExpression.cpp
@@ -0,0 +1,96 @@
+#include "src/storage/expressions/IfThenElseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        IfThenElseExpression::IfThenElseExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& condition, std::shared_ptr<BaseExpression const> const& thenExpression, std::shared_ptr<BaseExpression const> const& elseExpression) : BaseExpression(returnType), condition(condition), thenExpression(thenExpression), elseExpression(elseExpression) {
+            // Intentionally left empty.
+        }
+        
+        bool IfThenElseExpression::evaluateAsBool(Valuation const& valuation) const {
+            bool conditionValue = this->condition->evaluateAsBool(valuation);
+            if (conditionValue) {
+                return this->thenExpression->evaluateAsBool(valuation);
+            } else {
+                return this->elseExpression->evaluateAsBool(valuation);
+            }
+        }
+        
+        int_fast64_t IfThenElseExpression::evaluateAsInt(Valuation const& valuation) const {
+            bool conditionValue = this->condition->evaluateAsBool(valuation);
+            if (conditionValue) {
+                return this->thenExpression->evaluateAsInt(valuation);
+            } else {
+                return this->elseExpression->evaluateAsInt(valuation);
+            }
+        }
+        
+        double IfThenElseExpression::evaluateAsDouble(Valuation const& valuation) const {
+            bool conditionValue = this->condition->evaluateAsBool(valuation);
+            if (conditionValue) {
+                return this->thenExpression->evaluateAsDouble(valuation);
+            } else {
+                return this->elseExpression->evaluateAsDouble(valuation);
+            }
+        }
+        
+        bool IfThenElseExpression::isConstant() const {
+            return this->condition->isConstant() && this->thenExpression->isConstant() && this->elseExpression->isConstant();
+        }
+        
+        std::set<std::string> IfThenElseExpression::getVariables() const {
+            std::set<std::string> result = this->condition->getVariables();
+            std::set<std::string> tmp = this->thenExpression->getVariables();
+            result.insert(tmp.begin(), tmp.end());
+            tmp = this->elseExpression->getVariables();
+            result.insert(tmp.begin(), tmp.end());
+            return result;
+        }
+        
+        std::set<std::string> IfThenElseExpression::getConstants() const {
+            std::set<std::string> result = this->condition->getConstants();
+            std::set<std::string> tmp = this->thenExpression->getConstants();
+            result.insert(tmp.begin(), tmp.end());
+            tmp = this->elseExpression->getConstants();
+            result.insert(tmp.begin(), tmp.end());
+            return result;
+        }
+        
+        std::shared_ptr<BaseExpression const> IfThenElseExpression::simplify() const {
+            std::shared_ptr<BaseExpression const> conditionSimplified;
+            if (conditionSimplified->isTrue()) {
+                return this->thenExpression->simplify();
+            } else if (conditionSimplified->isFalse()) {
+                return this->elseExpression->simplify();
+            } else {
+                std::shared_ptr<BaseExpression const> thenExpressionSimplified = this->thenExpression->simplify();
+                std::shared_ptr<BaseExpression const> elseExpressionSimplified = this->elseExpression->simplify();
+                
+                if (conditionSimplified.get() == this->condition.get() && thenExpressionSimplified.get() == this->thenExpression.get() && elseExpressionSimplified.get() == this->elseExpression.get()) {
+                    return this->shared_from_this();
+                } else {
+                    return std::shared_ptr<BaseExpression>(new IfThenElseExpression(this->getReturnType(), conditionSimplified, thenExpressionSimplified, elseExpressionSimplified));
+                }
+            }
+        }
+        
+        void IfThenElseExpression::accept(ExpressionVisitor* visitor) const {
+            visitor->visit(this);
+        }
+        
+        std::shared_ptr<BaseExpression const> IfThenElseExpression::getCondition() const {
+            return this->condition;
+        }
+        
+        std::shared_ptr<BaseExpression const> IfThenElseExpression::getThenExpression() const {
+            return this->thenExpression;
+        }
+        
+        std::shared_ptr<BaseExpression const> IfThenElseExpression::getElseExpression() const {
+            return this->elseExpression;
+        }
+        
+        void IfThenElseExpression::printToStream(std::ostream& stream) const {
+            stream << "(" << *this->condition << " ? " << *this->thenExpression << " : " << *this->elseExpression << ")";
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/IfThenElseExpression.h b/src/storage/expressions/IfThenElseExpression.h
new file mode 100644
index 000000000..794a75bee
--- /dev/null
+++ b/src/storage/expressions/IfThenElseExpression.h
@@ -0,0 +1,74 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_IFTHENELSEEXPRESSION_H_
+#define STORM_STORAGE_EXPRESSIONS_IFTHENELSEEXPRESSION_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+
+namespace storm {
+    namespace expressions {
+        class IfThenElseExpression : public BaseExpression {
+        public:
+            /*!
+             * Creates an if-then-else expression with the given return type, condition and operands.
+             *
+             * @param returnType The return type of the expression.
+             * @param thenExpression The expression evaluated if the condition evaluates true.
+             * @param elseExpression The expression evaluated if the condition evaluates false.
+             */
+            IfThenElseExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& condition, std::shared_ptr<BaseExpression const> const& thenExpression, std::shared_ptr<BaseExpression const> const& elseExpression);
+            
+            // Instantiate constructors and assignments with their default implementations.
+            IfThenElseExpression(IfThenElseExpression const& other) = default;
+            IfThenElseExpression& operator=(IfThenElseExpression const& other) = default;
+            IfThenElseExpression(IfThenElseExpression&&) = default;
+            IfThenElseExpression& operator=(IfThenElseExpression&&) = default;
+            virtual ~IfThenElseExpression() = default;
+            
+            // Override base class methods.
+            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual bool isConstant() const override;
+            virtual std::set<std::string> getVariables() const override;
+            virtual std::set<std::string> getConstants() const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
+            virtual void accept(ExpressionVisitor* visitor) const override;
+            
+            /*!
+             * Retrieves the condition expression of the if-then-else expression.
+             *
+             * @return The condition expression of the if-then-else expression.
+             */
+            std::shared_ptr<BaseExpression const> getCondition() const;
+
+            /*!
+             * Retrieves the then expression of the if-then-else expression.
+             *
+             * @return The then expression of the if-then-else expression.
+             */
+            std::shared_ptr<BaseExpression const> getThenExpression() const;
+
+            /*!
+             * Retrieves the else expression of the if-then-else expression.
+             *
+             * @return The else expression of the if-then-else expression.
+             */
+            std::shared_ptr<BaseExpression const> getElseExpression() const;
+
+        protected:
+            // Override base class method.
+            virtual void printToStream(std::ostream& stream) const override;
+            
+        private:
+            // The condition of the if-then-else.
+            std::shared_ptr<BaseExpression const> condition;
+            
+            // The return expression of the if-part.
+            std::shared_ptr<BaseExpression const> thenExpression;
+
+            // The return expression of the else-part.
+            std::shared_ptr<BaseExpression const> elseExpression;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_IFTHENELSEEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index 878d06036..c3f2ea0a8 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -3,6 +3,7 @@
 
 #include "src/storage/expressions/SubstitutionVisitor.h"
 
+#include "src/storage/expressions/IfThenElseExpression.h"
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/BinaryRelationExpression.h"
@@ -29,6 +30,28 @@ namespace storm {
             return Expression(this->expressionStack.top());
         }
         
+        template<template<typename... Arguments> class MapType>
+        void SubstitutionVisitor<MapType>::visit(IfThenElseExpression const* expression) {
+            expression->getCondition()->accept(this);
+            std::shared_ptr<BaseExpression const> conditionExpression = expressionStack.top();
+            expressionStack.pop();
+            
+            expression->getThenExpression()->accept(this);
+            std::shared_ptr<BaseExpression const> thenExpression = expressionStack.top();
+            expressionStack.pop();
+
+            expression->getElseExpression()->accept(this);
+            std::shared_ptr<BaseExpression const> elseExpression = expressionStack.top();
+            expressionStack.pop();
+
+            // If the arguments did not change, we simply push the expression itself.
+            if (conditionExpression.get() == expression->getCondition().get() && thenExpression.get() == expression->getThenExpression().get() && elseExpression.get() == expression->getElseExpression().get()) {
+                this->expressionStack.push(expression->getSharedPointer());
+            } else {
+                this->expressionStack.push(std::shared_ptr<BaseExpression>(new IfThenElseExpression(expression->getReturnType(), conditionExpression, thenExpression, elseExpression)));
+            }
+        }
+        
         template<template<typename... Arguments> class MapType>
         void SubstitutionVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
             expression->getFirstOperand()->accept(this);
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index 4c3abc1e7..ad29ad6ab 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -28,6 +28,7 @@ namespace storm {
              */
             Expression substitute(BaseExpression const* expression);
             
+            virtual void visit(IfThenElseExpression const* expression) override;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
             virtual void visit(BinaryRelationExpression const* expression) override;
diff --git a/src/storage/prism/Assignment.cpp b/src/storage/prism/Assignment.cpp
index 2c639a535..d556f6332 100644
--- a/src/storage/prism/Assignment.cpp
+++ b/src/storage/prism/Assignment.cpp
@@ -6,13 +6,6 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        Assignment::Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(oldAssignment.getVariableName()), expression(oldAssignment.getExpression().substitute<std::map>(renaming)) {
-            auto renamingPair = renaming.find(oldAssignment.variableName);
-            if (renamingPair != renaming.end()) {
-                this->variableName = renamingPair->second;
-            }
-        }
-        
         std::string const& Assignment::getVariableName() const {
             return variableName;
         }
diff --git a/src/storage/prism/Assignment.h b/src/storage/prism/Assignment.h
index 955c8417e..2d4629e31 100644
--- a/src/storage/prism/Assignment.h
+++ b/src/storage/prism/Assignment.h
@@ -19,17 +19,7 @@ namespace storm {
              * @param lineNumber The line number in which the assignment is defined.
              */
             Assignment(std::string const& variableName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
-            /*!
-             * Creates a copy of the given assignment and performs the provided renaming.
-             *
-             * @param oldAssignment The assignment to copy.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
-             * @param filename The filename in which the assignment is defined.
-             * @param lineNumber The line number in which the assignment is defined.
-             */
-            Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
+                        
             // Create default implementations of constructors/assignment.
             Assignment() = default;
             Assignment(Assignment const& other) = default;
diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
index 0ce68d34d..c746e698d 100644
--- a/src/storage/prism/BooleanVariable.cpp
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -10,10 +10,6 @@ namespace storm {
             // Nothing to do here.
         }
         
-        BooleanVariable::BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : Variable(oldVariable, newName, renaming, filename, lineNumber) {
-            // Nothing to do here.
-        }
-        
         std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable) {
             stream << variable.getName() << ": bool " << variable.getInitialValueExpression() << ";";
             return stream;
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
index d01ebe69d..d52b8d0aa 100644
--- a/src/storage/prism/BooleanVariable.h
+++ b/src/storage/prism/BooleanVariable.h
@@ -35,18 +35,6 @@ namespace storm {
              */
             BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
-            /*!
-             * Creates a copy of the given boolean variable and performs the provided renaming.
-             *
-             * @param oldVariable The variable to copy.
-             * @param newName New name of this variable.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be
-             * replaced with.
-             * @param filename The filename in which the variable is defined.
-             * @param lineNumber The line number in which the variable is defined.
-             */
-            BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber);
-            
             friend std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable);
         };
         
diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index 468e0da2b..5ca424bb1 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -5,21 +5,6 @@ namespace storm {
         Command::Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), actionName(actionName), guardExpression(guardExpression), updates(updates), globalIndex(globalIndex) {
             // Nothing to do here.
         }
-        
-        Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), actionName(oldCommand.getActionName()), guardExpression(oldCommand.getGuardExpression().substitute<std::map>(renaming)), globalIndex(newGlobalIndex) {
-            // Rename the action name of the command.
-            auto const& namePair = renaming.find(this->actionName);
-            if (namePair != renaming.end()) {
-                this->actionName = namePair->second;
-            }
-            
-            // Rename the updates of the command.
-            this->updates.reserve(oldCommand.getNumberOfUpdates());
-            for (Update const& update : oldCommand.getUpdates()) {
-                this->updates.emplace_back(update, newGlobalUpdateIndex, renaming, filename, lineNumber);
-                ++newGlobalUpdateIndex;
-            }
-        }
 
         std::string const& Command::getActionName() const {
             return this->actionName;
diff --git a/src/storage/prism/Command.h b/src/storage/prism/Command.h
index 0173832e8..24510bfda 100644
--- a/src/storage/prism/Command.h
+++ b/src/storage/prism/Command.h
@@ -24,18 +24,6 @@ namespace storm {
              */
             Command(uint_fast64_t globalIndex, std::string const& actionName, storm::expressions::Expression const& guardExpression, std::vector<storm::prism::Update> const& updates, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
-            /*!
-             * Creates a copy of the given command and performs the provided renaming.
-             *
-             * @param oldCommand The command to copy.
-             * @param newGlobalIndex The global index of the copy of the command.
-             * @param newGlobalUpdateIndex The global starting index for the updates of the renamed command.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
-             * @param filename The filename in which the command is defined.
-             * @param lineNumber The line number in which the command is defined.
-             */
-            Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
             // Create default implementations of constructors/assignment.
             Command() = default;
             Command(Command const& other) = default;
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index e025a8636..2815d5a6c 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -10,10 +10,6 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        IntegerVariable::IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : Variable(oldVariable, newName, renaming, filename, lineNumber), lowerBoundExpression(oldVariable.getLowerBoundExpression().substitute<std::map>(renaming)), upperBoundExpression(oldVariable.getUpperBoundExpression().substitute<std::map>(renaming)) {
-            // Intentionally left empty.
-        }
-        
         storm::expressions::Expression const& IntegerVariable::getLowerBoundExpression() const {
             return this->lowerBoundExpression;
         }
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
index 919bab480..817752925 100644
--- a/src/storage/prism/IntegerVariable.h
+++ b/src/storage/prism/IntegerVariable.h
@@ -39,17 +39,6 @@ namespace storm {
              */
             IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
-            /*!
-             * Creates a copy of the given integer variable and performs the provided renaming.
-             *
-             * @param oldVariable The variable to copy.
-             * @param newName New name of this variable.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
-             * @param filename The filename in which the variable is defined.
-             * @param lineNumber The line number in which the variable is defined.
-             */
-            IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
             /*!
              * Retrieves an expression defining the lower bound for this integer variable.
              *
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 48544efff..2c87a2077 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -9,34 +9,7 @@ namespace storm {
             // Initialize the internal mappings for fast information retrieval.
             this->createMappings();
         }
-        
-        Module::Module(Module const& oldModule, std::string const& newModuleName, uint_fast64_t newGlobalCommandIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(newModuleName), booleanVariables(), integerVariables(), commands(), actions(), actionsToCommandIndexMap() {
-            // Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception is thrown.
-            for (auto const& booleanVariable : oldModule.getBooleanVariables()) {
-                auto const& renamingPair = renaming.find(booleanVariable.getName());
-                LOG_THROW(renamingPair != renaming.end(), storm::exceptions::InvalidArgumentException, "Boolean variable '" << booleanVariable.getName() << " was not renamed.");
-                this->booleanVariables.emplace_back(booleanVariable, renamingPair->second, renaming, filename, lineNumber);
-            }
-           
-            // Now do the same for the integer variables.
-            for (auto const& integerVariable : oldModule.getIntegerVariables()) {
-                auto const& renamingPair = renaming.find(integerVariable.getName());
-                LOG_THROW(renamingPair != renaming.end(), storm::exceptions::InvalidArgumentException, "Integer variable '" << integerVariable.getName() << " was not renamed.");
-                this->integerVariables.emplace_back(integerVariable, renamingPair->second, renaming, filename, lineNumber);
-            }
-            
-            // Now we are ready to clone all commands and rename them if requested.
-            this->commands.reserve(oldModule.getNumberOfCommands());
-            for (Command const& command : oldModule.getCommands()) {
-                this->commands.emplace_back(command, newGlobalCommandIndex, newGlobalUpdateIndex, renaming, filename, lineNumber);
-                ++newGlobalCommandIndex;
-                newGlobalUpdateIndex += this->commands.back().getNumberOfUpdates();
-            }
-            
-            // Finally, update internal mappings.
-            this->createMappings();
-        }
-        
+                
         std::size_t Module::getNumberOfBooleanVariables() const {
             return this->booleanVariables.size();
         }
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index 4a1608d22..45ccf4f8a 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -28,20 +28,6 @@ namespace storm {
              */
             Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
-            /*!
-             * Special copy constructor, implementing the module renaming functionality. This will create a new module
-             * having all identifiers renamed according to the given map.
-             *
-             * @param oldModule The module to be copied.
-             * @param newModuleName The name of the new module.
-             * @param newGlobalCommandIndex The global starting index for commands of the renamed module.
-             * @param newGlobalUpdateIndex The global starting index for the updates of the renamed module.
-             * @param renaming A mapping of identifiers to the new identifiers they are to be replaced with.
-             * @param filename The filename in which the module is defined.
-             * @param lineNumber The line number in which the module is defined.
-             */
-            Module(Module const& oldModule, std::string const& newModuleName, uint_fast64_t newGlobalCommandIndex, uint_fast64_t newGlobalUpdateIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
             // Create default implementations of constructors/assignment.
             Module() = default;
             Module(Module const& other) = default;
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index dc609b4ad..21c204b00 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -8,21 +8,6 @@ namespace storm {
             this->createAssignmentMapping();
         }
         
-        Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), likelihoodExpression(update.getLikelihoodExpression().substitute<std::map>(renaming)), assignments(), variableToAssignmentIndexMap(), globalIndex(newGlobalIndex) {
-            // Rename all assignments.
-            for (auto const& assignment : update.getAssignments()) {
-                auto const& namePair = renaming.find(assignment.getVariableName());
-                if (namePair != renaming.end()) {
-                    this->assignments.emplace_back(Assignment(assignment, renaming, filename, lineNumber));
-                } else {
-                    this->assignments.emplace_back(Assignment(assignment));
-                }
-            }
-
-            // Create the assignment mapping.
-            this->createAssignmentMapping();
-        }
-        
         storm::expressions::Expression const& Update::getLikelihoodExpression() const {
             return likelihoodExpression;
         }
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index 6f85ece29..a6e53ea50 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -21,17 +21,6 @@ namespace storm {
              */
             Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
-            /*!
-             * Creates a copy of the given update and performs the provided renaming.
-             *
-             * @param update The update that is to be copied.
-             * @param newGlobalIndex The global index of the resulting update.
-             * @param renaming A mapping from names that are to be renamed to the names they are to be replaced with.
-             * @param filename The filename in which the update is defined.
-             * @param lineNumber The line number in which the update is defined.
-             */
-            Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
             // Create default implementations of constructors/assignment.
             Update() = default;
             Update(Update const& other) = default;
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index 1729ba036..739d9ca5b 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -1,6 +1,6 @@
 #include "gtest/gtest.h"
 #include "storm-config.h"
-#include "src/parser/prismparser/PrismParser.h"
+#include "src/parser/PrismParser.h"
 
 TEST(PrismParser, SimpleParsingOnlyTest) {
     std::string testInput =
@@ -29,6 +29,19 @@ TEST(PrismParser, StandardModelParsingTest) {
     EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm", false));
 }
 
+TEST(PrismParser, StandardModelFullTest) {
+    storm::prism::Program result;
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/die.pm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/firewire.nm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3_5.pm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/two_dice.nm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm", true));
+}
+
 TEST(PrismParser, SimpleFullTest) {
     std::string testInput =
     R"(dtmc
@@ -56,6 +69,7 @@ TEST(PrismParser, ComplexFullTest) {
     
     formula test = a >= 10 & (max(a,b) > floor(e));
     formula test2 = a+b;
+    formula test3 = (a + b > 10 ? floor(a) : h) + a;
     
     global g : bool init false;
     global h : [0 .. b];
@@ -65,14 +79,14 @@ TEST(PrismParser, ComplexFullTest) {
         j : bool init c;
         k : [125..a] init a;
 
-        [a] test2&false -> (i'=true)&(h'=1+1) + 1 : (j'=floor(a) <= max(k, b) - 1 + k);
+        [a] test&false -> (i'=true)&(k'=1+1) + 1 : (k'=floor(a) <= max(k, b) - 1 + k);
     endmodule
                                               
     module mod2
         [b] (k > 3) & false & (min(a, 0) < max(h, k)) -> 1-e: (j'=(1-a) * 2 + floor(f));
     endmodule
     
-    module mod3 = mod2 [ x = y ] endmodule
+    module mod3 = mod1 [ i = i1, j = j1, k = k1 ] endmodule
                                                                
     label "mal" = max(a, 10) > 0;
                                                                
@@ -92,7 +106,6 @@ TEST(PrismParser, ComplexFullTest) {
     
     storm::prism::Program result;
     result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true);
-    std::cout << result << std::endl;
     EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType());
     EXPECT_EQ(3, result.getNumberOfModules());
     EXPECT_EQ(2, result.getNumberOfRewardModels());
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 6563a749d..8bb2e4c04 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -138,6 +138,14 @@ TEST(Expression, OperatorTest) {
     
     storm::expressions::Expression tempExpression;
 
+    ASSERT_THROW(tempExpression = trueExpression.ite(falseExpression, piExpression), storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = boolConstExpression.ite(threeExpression, doubleVarExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
+    ASSERT_NO_THROW(tempExpression = boolConstExpression.ite(threeExpression, intVarExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = boolConstExpression.ite(trueExpression, falseExpression));
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
     ASSERT_THROW(tempExpression = trueExpression + piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression + threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
@@ -367,4 +375,9 @@ TEST(Expression, SimpleEvaluationTest) {
     EXPECT_TRUE(tempExpression.evaluateAsBool(valuation));
     ASSERT_NO_THROW(valuation.setIntegerValue("y", 3));
     EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
+    
+    ASSERT_NO_THROW(tempExpression = ((intVarExpression < threeExpression).ite(trueExpression, falseExpression)));
+    ASSERT_THROW(tempExpression.evaluateAsDouble(valuation), storm::exceptions::InvalidTypeException);
+    ASSERT_THROW(tempExpression.evaluateAsInt(valuation), storm::exceptions::InvalidTypeException);
+    EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
 }
\ No newline at end of file

From a642ba6e72b488cbd3d3da33f6560db3c40364df Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 14 Apr 2014 22:00:06 +0200
Subject: [PATCH 071/147] Started adapting dependent classes to new PRISM
 classes.

Former-commit-id: 59155b5fc93e6f269ff6a369faa455eced54b3dd
---
 src/adapters/ExplicitModelAdapter.h           | 100 +++++++-----------
 .../MILPMinimalLabelSetGenerator.h            |   9 +-
 src/storage/expressions/SimpleValuation.cpp   |  42 ++++++++
 src/storage/expressions/SimpleValuation.h     |  37 +++++++
 src/storage/prism/Assignment.cpp              |   4 +
 src/storage/prism/Assignment.h                |   8 ++
 src/storage/prism/BooleanVariable.cpp         |   4 +
 src/storage/prism/BooleanVariable.h           |   8 ++
 src/storage/prism/Command.cpp                 |  10 ++
 src/storage/prism/Command.h                   |   8 ++
 src/storage/prism/Constant.cpp                |  13 +--
 src/storage/prism/Constant.h                  |  13 +--
 src/storage/prism/Formula.cpp                 |   4 +
 src/storage/prism/Formula.h                   |  10 ++
 src/storage/prism/IntegerVariable.cpp         |   4 +
 src/storage/prism/IntegerVariable.h           |   8 ++
 src/storage/prism/Label.cpp                   |   4 +
 src/storage/prism/Label.h                     |  10 ++
 src/storage/prism/Module.cpp                  |  22 ++++
 src/storage/prism/Module.h                    |   8 ++
 src/storage/prism/Program.cpp                 |  95 ++++++++++++++++-
 src/storage/prism/Program.h                   |  19 +++-
 src/storage/prism/RewardModel.cpp             |  15 +++
 src/storage/prism/RewardModel.h               |   9 ++
 src/storage/prism/StateReward.cpp             |   4 +
 src/storage/prism/StateReward.h               |  10 ++
 src/storage/prism/TransitionReward.cpp        |   4 +
 src/storage/prism/TransitionReward.h          |  10 ++
 src/storage/prism/Update.cpp                  |  10 ++
 src/storage/prism/Update.h                    |   8 ++
 30 files changed, 424 insertions(+), 86 deletions(-)

diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index f1ef50396..b06c24b21 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -16,11 +16,8 @@
 #include <boost/functional/hash.hpp>
 #include <boost/container/flat_set.hpp>
 
-#include "src/ir/Program.h"
-#include "src/ir/RewardModel.h"
-#include "src/ir/StateReward.h"
-#include "src/ir/TransitionReward.h"
-#include "src/utility/IRUtility.h"
+#include "src/storage/prism/Program.h"
+#include "src/storage/expressions/SimpleValuation.h"
 #include "src/models/AbstractModel.h"
 #include "src/models/Dtmc.h"
 #include "src/models/Ctmc.h"
@@ -29,20 +26,17 @@
 #include "src/models/AtomicPropositionsLabeling.h"
 #include "src/storage/SparseMatrix.h"
 #include "src/settings/Settings.h"
+#include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/WrongFormatException.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
-using namespace storm::utility::ir;
-
 namespace storm {
     namespace adapters {
                 
         template<typename ValueType>
         class ExplicitModelAdapter {
         public:
+            typedef storm::expressions::SimpleValuation StateType;
+            
             // A structure holding information about the reachable state space.
             struct StateInformation {
                 StateInformation() : reachableStates(), stateToIndexMap() {
@@ -53,7 +47,7 @@ namespace storm {
                 std::vector<StateType*> reachableStates;
                 
                 // A mapping from states to indices in the list of reachable states.
-                std::unordered_map<StateType*, uint_fast64_t, StateHash, StateCompare> stateToIndexMap;
+                std::unordered_map<StateType*, uint_fast64_t, storm::expressions::SimpleValuationPointerHash, storm::expressions::SimpleValuationPointerCompare> stateToIndexMap;
             };
             
             // A structure holding the individual components of a model.
@@ -90,24 +84,24 @@ namespace storm {
              * rewards.
              * @return The explicit model that was given by the probabilistic program.
              */
-            static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::ir::Program program, std::string const& constantDefinitionString = "", std::string const& rewardModelName = "") {
+            static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::prism::Program program, std::string const& constantDefinitionString = "", std::string const& rewardModelName = "") {
                 // Start by defining the undefined constants in the model.
-                defineUndefinedConstants(program, constantDefinitionString);
+                storm::prism::Program definedProgram = program.defineUndefinedConstants(constantDefinitions);
                 
-                ModelComponents modelComponents = buildModelComponents(program, rewardModelName);
+                ModelComponents modelComponents = buildModelComponents(definedProgram, rewardModelName);
                 
                 std::unique_ptr<storm::models::AbstractModel<ValueType>> result;
                 switch (program.getModelType()) {
-                    case storm::ir::Program::DTMC:
+                    case storm::prism::Program::ModelType::DTMC:
                         result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Dtmc<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
                         break;
-                    case storm::ir::Program::CTMC:
+                    case storm::prism::Program::ModelType::CTMC:
                         result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Ctmc<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
                         break;
-                    case storm::ir::Program::MDP:
+                    case storm::prism::Program::ModelType::MDP:
                         result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Mdp<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
                         break;
-                    case storm::ir::Program::CTMDP:
+                    case storm::prism::Program::ModelType::CTMDP:
                         result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Ctmdp<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
                         break;
                     default:
@@ -116,26 +110,10 @@ namespace storm {
                         break;
                 }
                 
-                // Undefine the constants so that the program can be used again somewhere else.
-                undefineUndefinedConstants(program);
-                
                 return result;
             }
             
         private:
-            /*!
-             * Transforms a state into a somewhat readable string.
-             *
-             * @param state The state to transform into a string.
-             * @return A string representation of the state.
-             */
-            static std::string toString(StateType const* state) {
-                std::stringstream ss;
-                for (unsigned int i = 0; i < state->first.size(); i++) ss << state->first[i] << "\t";
-                for (unsigned int i = 0; i < state->second.size(); i++) ss << state->second[i] << "\t";
-                return ss.str();
-            }
-            
             /*!
              * Applies an update to the given state and returns the resulting new state object. This methods does not
              * modify the given state but returns a new one.
@@ -145,7 +123,7 @@ namespace storm {
              * @params update The update to apply.
              * @return The resulting state.
              */
-            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::ir::Update const& update) {
+            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::prism::Update const& update) {
                 return applyUpdate(variableInformation, state, state, update);
             }
             
@@ -160,7 +138,7 @@ namespace storm {
              * @param update The update to apply.
              * @return The resulting state.
              */
-            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::ir::Update const& update) {
+            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
                 StateType* newState = new StateType(*state);
                 for (auto variableAssignmentPair : update.getBooleanAssignments()) {
                     setValue(newState, variableInformation.booleanVariableToIndexMap.at(variableAssignmentPair.first), variableAssignmentPair.second.getExpression()->getValueAsBool(baseState));
@@ -220,12 +198,12 @@ namespace storm {
              * @param action The action label to select.
              * @return A list of lists of active commands or nothing.
              */
-            static boost::optional<std::vector<std::list<storm::ir::Command>>> getActiveCommandsByAction(storm::ir::Program const& program, StateType const* state, std::string const& action) {
-                boost::optional<std::vector<std::list<storm::ir::Command>>> result((std::vector<std::list<storm::ir::Command>>()));
+            static boost::optional<std::vector<std::list<storm::prism::Command>>> getActiveCommandsByAction(storm::prism::Program const& program, StateType const* state, std::string const& action) {
+                boost::optional<std::vector<std::list<storm::prism::Command>>> result((std::vector<std::list<storm::prism::Command>>()));
                 
                 // Iterate over all modules.
                 for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
-                    storm::ir::Module const& module = program.getModule(i);
+                    storm::prism::Module const& module = program.getModule(i);
                     
                     // If the module has no command labeled with the given action, we can skip this module.
                     if (!module.hasAction(action)) {
@@ -237,14 +215,14 @@ namespace storm {
                     // If the module contains the action, but there is no command in the module that is labeled with
                     // this action, we don't have any feasible command combinations.
                     if (commandIndices.empty()) {
-                        return boost::optional<std::vector<std::list<storm::ir::Command>>>();
+                        return boost::optional<std::vector<std::list<storm::prism::Command>>>();
                     }
                     
-                    std::list<storm::ir::Command> commands;
+                    std::list<storm::prism::Command> commands;
                     
                     // Look up commands by their indices and add them if the guard evaluates to true in the given state.
                     for (uint_fast64_t commandIndex : commandIndices) {
-                        storm::ir::Command const& command = module.getCommand(commandIndex);
+                        storm::prism::Command const& command = module.getCommand(commandIndex);
                         if (command.getGuard()->getValueAsBool(state)) {
                             commands.push_back(command);
                         }
@@ -253,7 +231,7 @@ namespace storm {
                     // If there was no enabled command although the module has some command with the required action label,
                     // we must not return anything.
                     if (commands.size() == 0) {
-                        return boost::optional<std::vector<std::list<storm::ir::Command>>>();
+                        return boost::optional<std::vector<std::list<storm::prism::Command>>>();
                     }
                     
                     result.get().push_back(std::move(commands));
@@ -261,18 +239,18 @@ namespace storm {
                 return result;
             }
                         
-            static std::list<Choice<ValueType>> getUnlabeledTransitions(storm::ir::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
+            static std::list<Choice<ValueType>> getUnlabeledTransitions(storm::prism::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
                 std::list<Choice<ValueType>> result;
                 
                 StateType const* currentState = stateInformation.reachableStates[stateIndex];
 
                 // Iterate over all modules.
                 for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
-                    storm::ir::Module const& module = program.getModule(i);
+                    storm::prism::Module const& module = program.getModule(i);
                     
                     // Iterate over all commands.
                     for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) {
-                        storm::ir::Command const& command = module.getCommand(j);
+                        storm::prism::Command const& command = module.getCommand(j);
                         
                         // Only consider unlabeled commands.
                         if (command.getActionName() != "") continue;
@@ -286,7 +264,7 @@ namespace storm {
                         double probabilitySum = 0;
                         // Iterate over all updates of the current command.
                         for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) {
-                            storm::ir::Update const& update = command.getUpdate(k);
+                            storm::prism::Update const& update = command.getUpdate(k);
                             
                             // Obtain target state index.
                             std::pair<bool, uint_fast64_t> flagTargetStateIndexPair = getOrAddStateIndex(applyUpdate(variableInformation, currentState, update), stateInformation);
@@ -315,17 +293,17 @@ namespace storm {
                 return result;
             }
             
-            static std::list<Choice<ValueType>> getLabeledTransitions(storm::ir::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
+            static std::list<Choice<ValueType>> getLabeledTransitions(storm::prism::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
                 std::list<Choice<ValueType>> result;
                 
                 for (std::string const& action : program.getActions()) {
                     StateType const* currentState = stateInformation.reachableStates[stateIndex];
-                    boost::optional<std::vector<std::list<storm::ir::Command>>> optionalActiveCommandLists = getActiveCommandsByAction(program, currentState, action);
+                    boost::optional<std::vector<std::list<storm::prism::Command>>> optionalActiveCommandLists = getActiveCommandsByAction(program, currentState, action);
                     
                     // Only process this action label, if there is at least one feasible solution.
                     if (optionalActiveCommandLists) {
-                        std::vector<std::list<storm::ir::Command>> const& activeCommandList = optionalActiveCommandLists.get();
-                        std::vector<std::list<storm::ir::Command>::const_iterator> iteratorList(activeCommandList.size());
+                        std::vector<std::list<storm::prism::Command>> const& activeCommandList = optionalActiveCommandLists.get();
+                        std::vector<std::list<storm::prism::Command>::const_iterator> iteratorList(activeCommandList.size());
                         
                         // Initialize the list of iterators.
                         for (size_t i = 0; i < activeCommandList.size(); ++i) {
@@ -342,10 +320,10 @@ namespace storm {
                             // FIXME: This does not check whether a global variable is written multiple times. While the
                             // behaviour for this is undefined anyway, a warning should be issued in that case.
                             for (uint_fast64_t i = 0; i < iteratorList.size(); ++i) {
-                                storm::ir::Command const& command = *iteratorList[i];
+                                storm::prism::Command const& command = *iteratorList[i];
                                 
                                 for (uint_fast64_t j = 0; j < command.getNumberOfUpdates(); ++j) {
-                                    storm::ir::Update const& update = command.getUpdate(j);
+                                    storm::prism::Update const& update = command.getUpdate(j);
                                     
                                     for (auto const& stateProbabilityPair : *currentTargetStates) {
                                         StateType* newTargetState = applyUpdate(variableInformation, stateProbabilityPair.first, currentState, update);
@@ -459,7 +437,7 @@ namespace storm {
              * @return A tuple containing a vector with all rows at which the nondeterministic choices of each state begin
              * and a vector containing the labels associated with each choice.
              */
-            static std::vector<boost::container::flat_set<uint_fast64_t>> buildMatrices(storm::ir::Program const& program, VariableInformation const& variableInformation, std::vector<storm::ir::TransitionReward> const& transitionRewards, StateInformation& stateInformation, bool deterministicModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, storm::storage::SparseMatrixBuilder<ValueType>& transitionRewardMatrixBuilder) {
+            static std::vector<boost::container::flat_set<uint_fast64_t>> buildMatrices(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<storm::prism::TransitionReward> const& transitionRewards, StateInformation& stateInformation, bool deterministicModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, storm::storage::SparseMatrixBuilder<ValueType>& transitionRewardMatrixBuilder) {
                 std::vector<boost::container::flat_set<uint_fast64_t>> choiceLabels;
                 
                 // Initialize a queue and insert the initial state.
@@ -616,7 +594,7 @@ namespace storm {
              * is considered.
              * @return A structure containing the components of the resulting model.
              */
-            static ModelComponents buildModelComponents(storm::ir::Program const& program, std::string const& rewardModelName) {
+            static ModelComponents buildModelComponents(storm::prism::Program const& program, std::string const& rewardModelName) {
                 ModelComponents modelComponents;
                 
                 VariableInformation variableInformation = createVariableInformation(program);
@@ -625,11 +603,11 @@ namespace storm {
                 StateInformation stateInformation;
                 
                 // Get the selected reward model or create an empty one if none is selected.
-                storm::ir::RewardModel const& rewardModel = rewardModelName != "" ? program.getRewardModel(rewardModelName) : storm::ir::RewardModel();
+                storm::prism::RewardModel const& rewardModel = rewardModelName != "" ? program.getRewardModel(rewardModelName) : storm::prism::RewardModel();
                 
                 // Determine whether we have to combine different choices to one or whether this model can have more than
                 // one choice per state.
-                bool deterministicModel = program.getModelType() == storm::ir::Program::DTMC || program.getModelType() == storm::ir::Program::CTMC;
+                bool deterministicModel = program.getModelType() == storm::prism::Program::DTMC || program.getModelType() == storm::prism::Program::CTMC;
 
                 // Build the transition and reward matrices.
                 storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, 0, 0, !deterministicModel, 0);
@@ -662,8 +640,8 @@ namespace storm {
              * @param stateInformation Information about the state space of the program.
              * @return The state labeling of the given program.
              */
-            static storm::models::AtomicPropositionsLabeling buildStateLabeling(storm::ir::Program const& program, VariableInformation const& variableInformation, StateInformation const& stateInformation) {
-                std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels = program.getLabels();
+            static storm::models::AtomicPropositionsLabeling buildStateLabeling(storm::prism::Program const& program, VariableInformation const& variableInformation, StateInformation const& stateInformation) {
+                std::map<std::string, std::unique_ptr<storm::prism::expressions::BaseExpression>> const& labels = program.getLabels();
                 
                 storm::models::AtomicPropositionsLabeling result(stateInformation.reachableStates.size(), labels.size() + 1);
                 
@@ -697,7 +675,7 @@ namespace storm {
              * @param stateInformation Information about the state space.
              * @return A vector containing the state rewards for the state space.
              */
-            static std::vector<ValueType> buildStateRewards(std::vector<storm::ir::StateReward> const& rewards, StateInformation const& stateInformation) {
+            static std::vector<ValueType> buildStateRewards(std::vector<storm::prism::StateReward> const& rewards, StateInformation const& stateInformation) {
                 std::vector<ValueType> result(stateInformation.reachableStates.size());
                 for (uint_fast64_t index = 0; index < stateInformation.reachableStates.size(); index++) {
                     result[index] = ValueType(0);
diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index b73ff1590..197db76ab 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -11,7 +11,7 @@
 #include <chrono>
 
 #include "src/models/Mdp.h"
-#include "src/ir/Program.h"
+#include "src/storage/prism/Program.h"
 #include "src/exceptions/NotImplementedException.h"
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/exceptions/InvalidStateException.h"
@@ -1000,7 +1000,7 @@ namespace storm {
              * @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested
              * formula can be either an unbounded until formula or an eventually formula.
              */
-            static void computeCounterexample(storm::ir::Program const& program, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) {
+            static void computeCounterexample(storm::prism::Program const& program, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) {
                 std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl;
                 // First, we need to check whether the current formula is an Until-Formula.
                 storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr);
@@ -1045,9 +1045,8 @@ namespace storm {
                 std::cout << std::endl << "Computed minimal label set of size " << usedLabelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl;
 
                 std::cout << "Resulting program:" << std::endl;
-                storm::ir::Program restrictedProgram(program);
-                restrictedProgram.restrictCommands(usedLabelSet);
-                std::cout << restrictedProgram.toString() << std::endl;
+                storm::prism::Program restrictedProgram = program.restrictCommands(usedLabelSet);
+                std::cout << restrictedProgram << std::endl;
                 std::cout << std::endl << "-------------------------------------------" << std::endl;
                 
                 // FIXME: Return the DTMC that results from applying the max scheduler in the MDP restricted to the computed label set.
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index e2e230b64..7a456cb09 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -1,5 +1,7 @@
 #include "src/storage/expressions/SimpleValuation.h"
 
+#include <boost/functional/hash.hpp>
+
 namespace storm {
     namespace expressions {
         SimpleValuation::SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount) : identifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>), booleanValues(booleanVariableCount), integerValues(integerVariableCount), doubleValues(doubleVariableCount) {
@@ -9,6 +11,10 @@ namespace storm {
         SimpleValuation::SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues) : identifierToIndexMap(identifierToIndexMap), booleanValues(booleanValues), integerValues(integerValues), doubleValues(doubleValues) {
             // Intentionally left empty.
         }
+        
+        bool SimpleValuation::operator==(SimpleValuation const& other) const {
+            return this->identifierToIndexMap.get() == other.identifierToIndexMap.get() && this->booleanValues == other.booleanValues && this->integerValues == other.integerValues && this->doubleValues == other.doubleValues;
+        }
 
         void SimpleValuation::setIdentifierIndex(std::string const& name, uint_fast64_t index) {
             (*this->identifierToIndexMap)[name] = index;
@@ -58,5 +64,41 @@ namespace storm {
             
             return stream;
         }
+        
+        std::size_t SimpleValuationPointerHash::operator()(SimpleValuation* valuation) const {
+            size_t seed = 0;
+            for (auto const& value : valuation->booleanValues) {
+                boost::hash_combine<bool>(seed, value);
+            }
+            for (auto const& value : valuation->integerValues) {
+                boost::hash_combine<int_fast64_t>(seed, value);
+            }
+            for (auto const& value : valuation->doubleValues) {
+                boost::hash_combine<double>(seed, value);
+            }
+            return seed;
+        }
+        
+        bool SimpleValuationPointerCompare::operator()(SimpleValuation* valuation1, SimpleValuation* valuation2) const {
+            return *valuation1 == *valuation2;
+        }
+        
+        bool SimpleValuationPointerLess::operator()(SimpleValuation* valuation1, SimpleValuation* valuation2) const {
+            // Compare boolean variables.
+            bool less = valuation1->booleanValues < valuation2->booleanValues;
+            if (less) {
+                return true;
+            }
+            less = valuation1->integerValues < valuation2->integerValues;
+            if (less) {
+                return true;
+            }
+            less = valuation1->doubleValues < valuation2->doubleValues;
+            if (less) {
+                return true;
+            } else {
+                return false;
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 8f0e9d161..0cb3a00f6 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -12,6 +12,9 @@ namespace storm {
     namespace expressions {
         class SimpleValuation : public Valuation {
         public:
+            friend class SimpleValuationPointerHash;
+            friend class SimpleValuationPointerLess;
+            
             /*!
              * Creates a simple valuation that can hold the given number of boolean, integer and double variables.
              *
@@ -39,6 +42,11 @@ namespace storm {
             SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
             SimpleValuation& operator=(SimpleValuation&&) = default;
+
+            /*!
+             * Compares two simple valuations wrt. equality.
+             */
+            bool operator==(SimpleValuation const& other) const;
             
             /*!
              * Sets the index of the identifier with the given name to the given value.
@@ -92,6 +100,35 @@ namespace storm {
             // The value container for all double identifiers.
             std::vector<double> doubleValues;
         };
+        
+        /*!
+         * A helper class that can pe used as the hash functor for data structures that need to hash a simple valuations
+         * given via pointers.
+         */
+        class SimpleValuationPointerHash {
+        public:
+            std::size_t operator()(SimpleValuation* valuation) const;
+        };
+        
+        /*!
+         * A helper class that can be used as the comparison functor wrt. equality for data structures that need to
+         * store pointers to a simple valuations and need to compare the elements wrt. their content (rather than
+         * pointer equality).
+         */
+        class SimpleValuationPointerCompare {
+        public:
+            bool operator()(SimpleValuation* valuation1, SimpleValuation* valuation2) const;
+        };
+        
+        /*!
+         * A helper class that can be used as the comparison functor wrt. "<" for data structures that need to
+         * store pointers to a simple valuations and need to compare the elements wrt. their content (rather than
+         * pointer equality).
+         */
+        class SimpleValuationPointerLess {
+        public:
+            bool operator()(SimpleValuation* valuation1, SimpleValuation* valuation2) const;
+        };
     }
 }
 
diff --git a/src/storage/prism/Assignment.cpp b/src/storage/prism/Assignment.cpp
index d556f6332..f15797e6d 100644
--- a/src/storage/prism/Assignment.cpp
+++ b/src/storage/prism/Assignment.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return this->expression;
         }
         
+        Assignment Assignment::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return Assignment(this->getVariableName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Assignment const& assignment) {
             stream << "(" << assignment.getVariableName() << "' = " << assignment.getExpression() << ")";
             return stream;
diff --git a/src/storage/prism/Assignment.h b/src/storage/prism/Assignment.h
index 2d4629e31..cf71c8960 100644
--- a/src/storage/prism/Assignment.h
+++ b/src/storage/prism/Assignment.h
@@ -41,6 +41,14 @@ namespace storm {
              */
             storm::expressions::Expression const& getExpression() const;
             
+            /*!
+             * Substitutes all identifiers in the assignment according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting assignment.
+             */
+            Assignment substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Assignment const& assignment);
             
         private:
diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
index c746e698d..478b9322d 100644
--- a/src/storage/prism/BooleanVariable.cpp
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -10,6 +10,10 @@ namespace storm {
             // Nothing to do here.
         }
         
+        BooleanVariable BooleanVariable::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return BooleanVariable(this->getName(), this->getInitialValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable) {
             stream << variable.getName() << ": bool " << variable.getInitialValueExpression() << ";";
             return stream;
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
index d52b8d0aa..6c70fbafb 100644
--- a/src/storage/prism/BooleanVariable.h
+++ b/src/storage/prism/BooleanVariable.h
@@ -35,6 +35,14 @@ namespace storm {
              */
             BooleanVariable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
+            /*!
+             * Substitutes all identifiers in the boolean variable according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting boolean variable.
+             */
+            BooleanVariable substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable);
         };
         
diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index 5ca424bb1..f075ff6c6 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -30,6 +30,16 @@ namespace storm {
             return this->globalIndex;
         }
         
+        Command Command::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            std::vector<Update> newUpdates;
+            newUpdates.reserve(this->getNumberOfUpdates());
+            for (auto const& update : this->getUpdates()) {
+                newUpdates.emplace_back(update.substitute(substitution));
+            }
+            
+            return Command(this->getGlobalIndex(), this->getActionName(), this->getGuardExpression().substitute<std::map>(substitution), newUpdates, this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Command const& command) {
             stream << "[" << command.getActionName() << "] " << command.getGuardExpression() << " -> ";
             for (uint_fast64_t i = 0; i < command.getUpdates().size(); ++i) {
diff --git a/src/storage/prism/Command.h b/src/storage/prism/Command.h
index 24510bfda..91831d421 100644
--- a/src/storage/prism/Command.h
+++ b/src/storage/prism/Command.h
@@ -73,6 +73,14 @@ namespace storm {
              */
             uint_fast64_t getGlobalIndex() const;
             
+            /*!
+             * Substitutes all identifiers in the command according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting command.
+             */
+            Command substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Command const& command);
             
         private:
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index b57bf32d3..83e5f9b2a 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -2,11 +2,11 @@
 
 namespace storm {
     namespace prism {
-        Constant::Constant(ConstantType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(true), expression(expression) {
+        Constant::Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(true), expression(expression) {
             // Intentionally left empty.
         }
         
-        Constant::Constant(ConstantType constantType, std::string const& constantName, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(false), expression() {
+        Constant::Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(false), expression() {
             // Intentionally left empty.
         }
         
@@ -14,7 +14,7 @@ namespace storm {
             return this->constantName;
         }
         
-        Constant::ConstantType Constant::getConstantType() const {
+        storm::expressions::ExpressionReturnType Constant::getConstantType() const {
             return this->constantType;
         }
         
@@ -29,9 +29,10 @@ namespace storm {
         std::ostream& operator<<(std::ostream& stream, Constant const& constant) {
             stream << "const ";
             switch (constant.getConstantType()) {
-                case Constant::ConstantType::Bool: stream << "bool "; break;
-                case Constant::ConstantType::Integer: stream << "int "; break;
-                case Constant::ConstantType::Double: stream << "double "; break;
+                case storm::expressions::ExpressionReturnType::Undefined: stream << "undefined "; break;
+                case storm::expressions::ExpressionReturnType::Bool: stream << "bool "; break;
+                case storm::expressions::ExpressionReturnType::Int: stream << "int "; break;
+                case storm::expressions::ExpressionReturnType::Double: stream << "double "; break;
             }
             stream << constant.getConstantName();
             if (constant.isDefined()) {
diff --git a/src/storage/prism/Constant.h b/src/storage/prism/Constant.h
index ad1736ffd..b67e1639f 100644
--- a/src/storage/prism/Constant.h
+++ b/src/storage/prism/Constant.h
@@ -8,11 +8,6 @@ namespace storm {
     namespace prism {
         class Constant : public LocatedInformation {
         public:
-            /*!
-             * The possible constant types.
-             */
-            enum class ConstantType {Bool, Integer, Double};
-            
             /*!
              * Creates a constant with the given type, name and defining expression.
              *
@@ -22,7 +17,7 @@ namespace storm {
              * @param filename The filename in which the transition reward is defined.
              * @param lineNumber The line number in which the transition reward is defined.
              */
-            Constant(ConstantType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
 
             /*!
              * Creates an undefined constant with the given type and name.
@@ -32,7 +27,7 @@ namespace storm {
              * @param filename The filename in which the transition reward is defined.
              * @param lineNumber The line number in which the transition reward is defined.
              */
-            Constant(ConstantType constantType, std::string const& constantName, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Constant() = default;
@@ -53,7 +48,7 @@ namespace storm {
              *
              * @return The type of the constant;
              */
-            ConstantType getConstantType() const;
+            storm::expressions::ExpressionReturnType getConstantType() const;
             
             /*!
              * Retrieves whether the constant is defined, i.e., whether there is an expression defining its value.
@@ -74,7 +69,7 @@ namespace storm {
             
         private:
             // The type of the constant.
-            ConstantType constantType;
+            storm::expressions::ExpressionReturnType constantType;
             
             // The name of the constant.
             std::string constantName;
diff --git a/src/storage/prism/Formula.cpp b/src/storage/prism/Formula.cpp
index e665f22f7..875438441 100644
--- a/src/storage/prism/Formula.cpp
+++ b/src/storage/prism/Formula.cpp
@@ -18,6 +18,10 @@ namespace storm {
             return this->getExpression().getReturnType();
         }
         
+        Formula Formula::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return Formula(this->getFormulaName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Formula const& formula) {
             stream << "formula " << formula.getFormulaName() << " = " << formula.getExpression() << ";";
             return stream;
diff --git a/src/storage/prism/Formula.h b/src/storage/prism/Formula.h
index 4ae67b9dd..d507aebb1 100644
--- a/src/storage/prism/Formula.h
+++ b/src/storage/prism/Formula.h
@@ -1,6 +1,8 @@
 #ifndef STORM_STORAGE_PRISM_FORMULA_H_
 #define STORM_STORAGE_PRISM_FORMULA_H_
 
+#include <map>
+
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
@@ -47,6 +49,14 @@ namespace storm {
              */
             storm::expressions::ExpressionReturnType getReturnType() const;
             
+            /*!
+             * Substitutes all identifiers in the expression of the formula according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting formula.
+             */
+            Formula substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Formula const& formula);
             
         private:
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index 2815d5a6c..2655dd266 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -18,6 +18,10 @@ namespace storm {
             return this->upperBoundExpression;
         }
         
+        IntegerVariable IntegerVariable::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return IntegerVariable(this->getName(), this->getLowerBoundExpression().substitute<std::map>(substitution), this->getUpperBoundExpression().substitute<std::map>(substitution), this->getInitialValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable) {
             stream << variable.getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << " init " << variable.getInitialValueExpression() << ";";
             return stream;
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
index 817752925..f85e58701 100644
--- a/src/storage/prism/IntegerVariable.h
+++ b/src/storage/prism/IntegerVariable.h
@@ -53,6 +53,14 @@ namespace storm {
              */
             storm::expressions::Expression const& getUpperBoundExpression() const;
             
+            /*!
+             * Substitutes all identifiers in the boolean variable according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting boolean variable.
+             */
+            IntegerVariable substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable);
             
         private:
diff --git a/src/storage/prism/Label.cpp b/src/storage/prism/Label.cpp
index 297d8691e..51feae5b4 100644
--- a/src/storage/prism/Label.cpp
+++ b/src/storage/prism/Label.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return this->statePredicateExpression;
         }
         
+        Label Label::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return Label(this->getLabelName(), this->getStatePredicateExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Label const& label) {
             stream << "label \"" << label.getLabelName() << "\" = " << label.getStatePredicateExpression() << ";";
             return stream;
diff --git a/src/storage/prism/Label.h b/src/storage/prism/Label.h
index d1ae6e0fd..18899b41d 100644
--- a/src/storage/prism/Label.h
+++ b/src/storage/prism/Label.h
@@ -1,6 +1,8 @@
 #ifndef STORM_STORAGE_PRISM_LABEL_H_
 #define STORM_STORAGE_PRISM_LABEL_H_
 
+#include <map>
+
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
@@ -40,6 +42,14 @@ namespace storm {
              */
             storm::expressions::Expression const& getStatePredicateExpression() const;
             
+            /*!
+             * Substitutes all identifiers in the expression of the label according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting label.
+             */
+            Label substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Label const& label);
             
         private:
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 2c87a2077..f17e1bc12 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -127,6 +127,28 @@ namespace storm {
             return Module(this->getName(), this->getBooleanVariables(), this->getIntegerVariables(), newCommands);
         }
         
+        Module Module::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            std::vector<BooleanVariable> newBooleanVariables;
+            newBooleanVariables.reserve(this->getNumberOfBooleanVariables());
+            for (auto const& booleanVariable : this->getBooleanVariables()) {
+                newBooleanVariables.emplace_back(booleanVariable.substitute(substitution));
+            }
+            
+            std::vector<IntegerVariable> newIntegerVariables;
+            newBooleanVariables.reserve(this->getNumberOfIntegerVariables());
+            for (auto const& integerVariable : this->getIntegerVariables()) {
+                newIntegerVariables.emplace_back(integerVariable.substitute(substitution));
+            }
+            
+            std::vector<Command> newCommands;
+            newCommands.reserve(this->getNumberOfCommands());
+            for (auto const& command : this->getCommands()) {
+                newCommands.emplace_back(command.substitute(substitution));
+            }
+            
+            return Module(this->getName(), newBooleanVariables, newIntegerVariables, newCommands, this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Module const& module) {
             stream << "module " << module.getName() << std::endl;
             for (auto const& booleanVariable : module.getBooleanVariables()) {
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index 45ccf4f8a..ba23c23c5 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -146,6 +146,14 @@ namespace storm {
              */
             Module restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) const;
             
+            /*!
+             * Substitutes all identifiers in the module according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting module.
+             */
+            Module substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Module const& module);
 
         private:
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 98bb75a1a..564665fc0 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -25,6 +25,10 @@ namespace storm {
         std::vector<Constant> const& Program::getConstants() const {
             return this->constants;
         }
+        
+        std::size_t Program::getNumberOfConstants() const {
+            return this->getConstants().size();
+        }
 
         std::vector<BooleanVariable> const& Program::getGlobalBooleanVariables() const {
             return this->globalBooleanVariables;
@@ -59,7 +63,7 @@ namespace storm {
         }
         
         std::size_t Program::getNumberOfFormulas() const {
-            return this->formulas.size();
+            return this->getFormulas().size();
         }
         
         std::size_t Program::getNumberOfModules() const {
@@ -125,7 +129,7 @@ namespace storm {
         }
         
         std::size_t Program::getNumberOfRewardModels() const {
-            return this->rewardModels.size();
+            return this->getRewardModels().size();
         }
         
         storm::prism::RewardModel const& Program::getRewardModel(std::string const& name) const {
@@ -139,10 +143,10 @@ namespace storm {
         }
         
         std::size_t Program::getNumberOfLabels() const {
-            return this->labels.size();
+            return this->getLabels().size();
         }
         
-        Program Program::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
+        Program Program::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) const {
             std::vector<storm::prism::Module> newModules;
             newModules.reserve(this->getNumberOfModules());
             
@@ -198,6 +202,89 @@ namespace storm {
 
         }
         
+        Program Program::defineUndefinedConstants(std::map<std::string, storm::expressions::Expression> const& constantDefinitions) const {
+            // For sanity checking, we keep track of all undefined constants that we define in the course of this
+            // procedure.
+            std::set<std::string> definedUndefinedConstants;
+            
+            std::vector<Constant> newConstants;
+            newConstants.reserve(this->getNumberOfConstants());
+            for (auto const& constant : this->getConstants()) {
+                // If the constant is already defined, we need to replace the appearances of undefined constants in its
+                // defining expression
+                if (constant.isDefined()) {
+                    // Make sure we are not trying to define an already defined constant.
+                    LOG_THROW(constantDefinitions.find(constant.getConstantName()) == constantDefinitions.end(), storm::exceptions::InvalidArgumentException, "Illegally defining already defined constant '" << constant.getConstantName() << "'.");
+                    
+                    // Now replace the occurrences of undefined constants in its defining expression.
+                    newConstants.emplace_back(constant.getConstantType(), constant.getConstantName(), constant.getExpression().substitute<std::map>(constantDefinitions), constant.getFilename(), constant.getLineNumber());
+                } else {
+                    auto const& variableExpressionPair = constantDefinitions.find(constant.getConstantName());
+                    
+                    // If the constant is not defined by the mapping, we leave it like it is.
+                    if (variableExpressionPair == constantDefinitions.end()) {
+                        newConstants.emplace_back(constant);
+                    } else {
+                        // Otherwise, we add it to the defined constants and assign it the appropriate expression.
+                        definedUndefinedConstants.insert(constant.getConstantName());
+                        
+                        // Make sure the type of the constant is correct.
+                        LOG_THROW(variableExpressionPair->second.getReturnType() == constant.getConstantType(), storm::exceptions::InvalidArgumentException, "Illegal type of expression defining constant '" << constant.getConstantName() << "'.");
+                        
+                        // Now create the defined constant.
+                        newConstants.emplace_back(constant.getConstantType(), constant.getConstantName(), variableExpressionPair->second, constant.getFilename(), constant.getLineNumber());
+                    }
+                }
+            }
+            
+            // As a sanity check, we make sure that the given mapping does not contain any definitions for identifiers
+            // that are not undefined constants.
+            for (auto const& constantExpressionPair : constantDefinitions) {
+                LOG_THROW(definedUndefinedConstants.find(constantExpressionPair.first) != definedUndefinedConstants.end(), storm::exceptions::InvalidArgumentException, "Unable to define non-existant constant.");
+            }
+            
+            // Now we can substitute the constants in all expressions appearing in the program.
+            std::vector<BooleanVariable> newBooleanVariables;
+            newBooleanVariables.reserve(this->getNumberOfGlobalBooleanVariables());
+            for (auto const& booleanVariable : this->getGlobalBooleanVariables()) {
+                newBooleanVariables.emplace_back(booleanVariable.substitute(constantDefinitions));
+            }
+            
+            std::vector<IntegerVariable> newIntegerVariables;
+            newBooleanVariables.reserve(this->getNumberOfGlobalIntegerVariables());
+            for (auto const& integerVariable : this->getGlobalIntegerVariables()) {
+                newIntegerVariables.emplace_back(integerVariable.substitute(constantDefinitions));
+            }
+        
+            std::vector<Formula> newFormulas;
+            newFormulas.reserve(this->getNumberOfFormulas());
+            for (auto const& formula : this->getFormulas()) {
+                newFormulas.emplace_back(formula.substitute(constantDefinitions));
+            }
+
+            std::vector<Module> newModules;
+            newModules.reserve(this->getNumberOfModules());
+            for (auto const& module : this->getModules()) {
+                newModules.emplace_back(module.substitute(constantDefinitions));
+            }
+            
+            std::vector<RewardModel> newRewardModels;
+            newRewardModels.reserve(this->getNumberOfRewardModels());
+            for (auto const& rewardModel : this->getRewardModels()) {
+                newRewardModels.emplace_back(rewardModel.substitute(constantDefinitions));
+            }
+            
+            storm::expressions::Expression newInitialStateExpression = this->getInitialStatesExpression().substitute<std::map>(constantDefinitions);
+            
+            std::vector<Label> newLabels;
+            newLabels.reserve(this->getNumberOfLabels());
+            for (auto const& label : this->getLabels()) {
+                newLabels.emplace_back(label.substitute(constantDefinitions));
+            }
+            
+            return Program(this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
             switch (program.getModelType()) {
                 case Program::ModelType::UNDEFINED: stream << "undefined"; break;
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 93e8ffccd..cd3e62345 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -72,6 +72,13 @@ namespace storm {
              */
             std::vector<Constant> const& getConstants() const;
             
+            /*!
+             * Retrieves the number of all constants defined in the program.
+             *
+             * @return The number of constants defined in the program.
+             */
+            std::size_t getNumberOfConstants() const;
+            
             /*!
              * Retrieves the global boolean variables of the program.
              *
@@ -239,7 +246,17 @@ namespace storm {
              *
              * @param indexSet The set of indices for which to keep the commands.
              */
-            Program restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
+            Program restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) const;
+            
+            /*!
+             * Defines the undefined constants according to the given map and returns the resulting program.
+             *
+             * @param constantDefinitions A mapping from undefined constant names to the expressions they are supposed
+             * to be replaced with.
+             * @return The program after all undefined constants in the given map have been replaced with their
+             * definitions.
+             */
+            Program defineUndefinedConstants(std::map<std::string, storm::expressions::Expression> const& constantDefinitions) const;
             
             friend std::ostream& operator<<(std::ostream& stream, Program const& program);
             
diff --git a/src/storage/prism/RewardModel.cpp b/src/storage/prism/RewardModel.cpp
index a25d58fc9..a6c68b34f 100644
--- a/src/storage/prism/RewardModel.cpp
+++ b/src/storage/prism/RewardModel.cpp
@@ -26,6 +26,21 @@ namespace storm {
             return this->transitionRewards;
         }
         
+        RewardModel RewardModel::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            std::vector<StateReward> newStateRewards;
+            newStateRewards.reserve(this->getStateRewards().size());
+            for (auto const& stateReward : this->getStateRewards()) {
+                newStateRewards.emplace_back(stateReward.substitute(substitution));
+            }
+            
+            std::vector<TransitionReward> newTransitionRewards;
+            newTransitionRewards.reserve(this->getTransitionRewards().size());
+            for (auto const& transitionReward : this->getTransitionRewards()) {
+                newTransitionRewards.emplace_back(transitionReward.substitute(substitution));
+            }
+            return RewardModel(this->getName(), newStateRewards, newTransitionRewards, this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, RewardModel const& rewardModel) {
             stream << "rewards \"" << rewardModel.getName() << "\"" << std::endl;
             for (auto const& reward : rewardModel.getStateRewards()) {
diff --git a/src/storage/prism/RewardModel.h b/src/storage/prism/RewardModel.h
index 9e9498843..be43834e1 100644
--- a/src/storage/prism/RewardModel.h
+++ b/src/storage/prism/RewardModel.h
@@ -3,6 +3,7 @@
 
 #include <string>
 #include <vector>
+#include <map>
 
 #include "src/storage/prism/StateReward.h"
 #include "src/storage/prism/TransitionReward.h"
@@ -64,6 +65,14 @@ namespace storm {
              */
             std::vector<storm::prism::TransitionReward> const& getTransitionRewards() const;
             
+            /*!
+             * Substitutes all identifiers in the reward model according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting reward model.
+             */
+            RewardModel substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, RewardModel const& rewardModel);
 
         private:
diff --git a/src/storage/prism/StateReward.cpp b/src/storage/prism/StateReward.cpp
index 7e36406c5..ab2f0974b 100644
--- a/src/storage/prism/StateReward.cpp
+++ b/src/storage/prism/StateReward.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return this->rewardValueExpression;
         }
         
+        StateReward StateReward::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return StateReward(this->getStatePredicateExpression().substitute<std::map>(substitution), this->getRewardValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, StateReward const& stateReward) {
             stream << "\t" << stateReward.getStatePredicateExpression() << ": " << stateReward.getRewardValueExpression() << ";";
             return stream;
diff --git a/src/storage/prism/StateReward.h b/src/storage/prism/StateReward.h
index 5eb98886f..ea6050855 100644
--- a/src/storage/prism/StateReward.h
+++ b/src/storage/prism/StateReward.h
@@ -1,6 +1,8 @@
 #ifndef STORM_STORAGE_PRISM_STATEREWARD_H_
 #define STORM_STORAGE_PRISM_STATEREWARD_H_
 
+#include <map>
+
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
@@ -40,6 +42,14 @@ namespace storm {
              */
             storm::expressions::Expression const& getRewardValueExpression() const;
             
+            /*!
+             * Substitutes all identifiers in the state reward according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting state reward.
+             */
+            StateReward substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, StateReward const& stateReward);
 
         private:
diff --git a/src/storage/prism/TransitionReward.cpp b/src/storage/prism/TransitionReward.cpp
index a5b81e55f..0034231d8 100644
--- a/src/storage/prism/TransitionReward.cpp
+++ b/src/storage/prism/TransitionReward.cpp
@@ -18,6 +18,10 @@ namespace storm {
             return this->rewardValueExpression;
         }
         
+        TransitionReward TransitionReward::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return TransitionReward(this->getActionName(), this->getStatePredicateExpression().substitute<std::map>(substitution), this->getRewardValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, TransitionReward const& transitionReward) {
             stream << "\t[" << transitionReward.getActionName() << "] " << transitionReward.getStatePredicateExpression() << ": " << transitionReward.getRewardValueExpression() << ";";
             return stream;
diff --git a/src/storage/prism/TransitionReward.h b/src/storage/prism/TransitionReward.h
index 1232e5b51..987d7dc89 100644
--- a/src/storage/prism/TransitionReward.h
+++ b/src/storage/prism/TransitionReward.h
@@ -1,6 +1,8 @@
 #ifndef STORM_STORAGE_PRISM_TRANSITIONREWARD_H_
 #define STORM_STORAGE_PRISM_TRANSITIONREWARD_H_
 
+#include <map>
+
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
@@ -49,6 +51,14 @@ namespace storm {
              */
             storm::expressions::Expression const& getRewardValueExpression() const;
             
+            /*!
+             * Substitutes all identifiers in the transition reward according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting transition reward.
+             */
+            TransitionReward substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, TransitionReward const& transitionReward);
 
         private:
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index 21c204b00..2e01187c9 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -37,6 +37,16 @@ namespace storm {
             }
         }
         
+        Update Update::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            std::vector<Assignment> newAssignments;
+            newAssignments.reserve(this->getNumberOfAssignments());
+            for (auto const& assignment : this->getAssignments()) {
+                newAssignments.emplace_back(assignment.substitute(substitution));
+            }
+            
+            return Update(this->getGlobalIndex(), this->getLikelihoodExpression().substitute<std::map>(substitution), newAssignments, this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Update const& update) {
             stream << update.getLikelihoodExpression() << " : ";
             uint_fast64_t i = 0;
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index a6e53ea50..176111acb 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -63,6 +63,14 @@ namespace storm {
              */
             uint_fast64_t getGlobalIndex() const;
             
+            /*!
+             * Substitutes all identifiers in the update according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting update.
+             */
+            Update substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Update const& assignment);
             
         private:

From d9345b19e97856be286bcf8bf76f244f740cbf8a Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 15 Apr 2014 15:55:19 +0200
Subject: [PATCH 072/147] Further work on adapting explicit model generator to
 new PRISM classes.

Former-commit-id: 01cefceb52e3bc80d7b025f77bed154f12e29069
---
 src/adapters/ExplicitModelAdapter.h       | 78 +++++++++++++++++++++--
 src/parser/PrismParser.cpp                | 12 ++--
 src/storage/expressions/SimpleValuation.h |  1 +
 src/storage/prism/Program.cpp             | 16 ++++-
 src/storage/prism/Program.h               | 19 ++++++
 src/utility/IRUtility.h                   |  2 +-
 6 files changed, 114 insertions(+), 14 deletions(-)

diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index b06c24b21..be293ebf6 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -15,6 +15,7 @@
 #include <queue>
 #include <boost/functional/hash.hpp>
 #include <boost/container/flat_set.hpp>
+#include <boost/algorithm/string.hpp>
 
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/SimpleValuation.h"
@@ -72,6 +73,62 @@ namespace storm {
                 std::vector<boost::container::flat_set<uint_fast64_t>> choiceLabeling;
             };
             
+            static std::map<std::string, storm::expressions::Expression> parseConstantDefinitionString(storm::prism::Program const& program, std::string const& constantDefinitionString) {
+                std::map<std::string, storm::expressions::Expression> constantDefinitions;
+                std::set<std::string> definedConstants;
+                
+                if (!constantDefinitionString.empty()) {
+                    // Parse the string that defines the undefined constants of the model and make sure that it contains exactly
+                    // one value for each undefined constant of the model.
+                    std::vector<std::string> definitions;
+                    boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
+                    for (auto& definition : definitions) {
+                        boost::trim(definition);
+                        
+                        // Check whether the token could be a legal constant definition.
+                        uint_fast64_t positionOfAssignmentOperator = definition.find('=');
+                        if (positionOfAssignmentOperator == std::string::npos) {
+                            throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: syntax error.";
+                        }
+                        
+                        // Now extract the variable name and the value from the string.
+                        std::string constantName = definition.substr(0, positionOfAssignmentOperator);
+                        boost::trim(constantName);
+                        std::string value = definition.substr(positionOfAssignmentOperator + 1);
+                        boost::trim(value);
+                        
+                        // Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
+                        if (program.hasConstant(constantName)) {
+                            // Get the actual constant and check whether it's in fact undefined.
+                            auto const& constant = program.getConstant(constantName);
+                            LOG_THROW(!constant.isDefined(), storm::exceptions::InvalidArgumentException, "Illegally trying to define already defined constant '" << constantName <<"'.");
+                            LOG_THROW(definedConstants.find(constantName) == definedConstants.end(), storm::exceptions::InvalidArgumentException, "Illegally trying to define constant '" << constantName <<"' twice.");
+                            definedConstants.insert(constantName);
+                            
+                            if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Bool) {
+                                if (value == "true") {
+                                    constantDefinitions[constantName] = storm::expressions::Expression::createTrue();
+                                } else if (value == "false") {
+                                    constantDefinitions[constantName] = storm::expressions::Expression::createFalse();
+                                } else {
+                                    throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
+                                }
+                            } else if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Int) {
+                                int_fast64_t integerValue = std::stoi(value);
+                                constantDefinitions[constantName] = storm::expressions::Expression::createIntegerLiteral(integerValue);
+                            } else if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Double) {
+                                double doubleValue = std::stod(value);
+                                constantDefinitions[constantName] = storm::expressions::Expression::createDoubleLiteral(doubleValue);
+                            }
+                        } else {
+                            throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: unknown undefined constant " << constantName << ".";
+                        }
+                    }
+                }
+                
+                return constantDefinitions;
+            }
+            
             /*!
              * Convert the program given at construction time to an abstract model. The type of the model is the one
              * specified in the program. The given reward model name selects the rewards that the model will contain.
@@ -86,7 +143,11 @@ namespace storm {
              */
             static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::prism::Program program, std::string const& constantDefinitionString = "", std::string const& rewardModelName = "") {
                 // Start by defining the undefined constants in the model.
+                // First, we need to parse the constant definition string.
+                std::map<std::string, storm::expressions::Expression> constantDefinitions = parseConstantDefinitionString(program, constantDefinitionString);
+                
                 storm::prism::Program definedProgram = program.defineUndefinedConstants(constantDefinitions);
+                LOG_THROW(!definedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
                 
                 ModelComponents modelComponents = buildModelComponents(definedProgram, rewardModelName);
                 
@@ -118,13 +179,12 @@ namespace storm {
              * Applies an update to the given state and returns the resulting new state object. This methods does not
              * modify the given state but returns a new one.
              *
-             * @param variableInformation A structure with information about the variables in the program.
              * @params state The state to which to apply the update.
              * @params update The update to apply.
              * @return The resulting state.
              */
-            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::prism::Update const& update) {
-                return applyUpdate(variableInformation, state, state, update);
+            static StateType* applyUpdate(StateType const* state, storm::prism::Update const& update) {
+                return applyUpdate(state, state, update);
             }
             
             /*!
@@ -132,14 +192,22 @@ namespace storm {
              * over the variable values of the given base state. This methods does not modify the given state but
              * returns a new one.
              *
-             * @param variableInformation A structure with information about the variables in the program.
              * @param state The state to which to apply the update.
              * @param baseState The state used for evaluating the update.
              * @param update The update to apply.
              * @return The resulting state.
              */
-            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
+            static StateType* applyUpdate(StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
                 StateType* newState = new StateType(*state);
+                for (auto const& assignment : update.getAssignments()) {
+                    switch (assignment.getExpression().getReturnType()) {
+                        case storm::expressions::ExpressionReturnType::Bool: newState->setBooleanValue(assignment.getVariableName(), assignment.getExpression().evaluateAsBool(*baseState)); break;
+                        case storm::expressions::ExpressionReturnType::Int:
+                            int_fast64_t newValue = assignment.getExpression().evaluateAsInt(*baseState));
+                            newState->setIntegerValue(assignment.getVariableName(), assignment.getExpression().evaluateAsInt(*baseState)); break;
+                        default: LOG_ASSERT(false, "Invalid type of assignment.");
+                    }
+                }
                 for (auto variableAssignmentPair : update.getBooleanAssignments()) {
                     setValue(newState, variableInformation.booleanVariableToIndexMap.at(variableAssignmentPair.first), variableAssignmentPair.second.getExpression()->getValueAsBool(baseState));
                 }
diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 71843541b..c1a068d5c 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -464,32 +464,32 @@ namespace storm {
         
         storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
             this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
-            return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, this->getFilename());
+            return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
             this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
-            return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, this->getFilename());
+            return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
             this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
-            return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, this->getFilename());
+            return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
-            return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, expression, this->getFilename());
+            return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, expression, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
-            return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, expression, this->getFilename());
+            return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, expression, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
-            return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, expression, this->getFilename());
+            return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, expression, this->getFilename());
         }
         
         storm::prism::Formula PrismParser::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 0cb3a00f6..0c2231a63 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -42,6 +42,7 @@ namespace storm {
             SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
             SimpleValuation& operator=(SimpleValuation&&) = default;
+            virtual ~SimpleValuation() = default;
 
             /*!
              * Compares two simple valuations wrt. equality.
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 564665fc0..c635cbf63 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace prism {
-        Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+        Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), constantToIndexMap(), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
             this->createMappings();
         }
         
@@ -22,6 +22,15 @@ namespace storm {
             return true;
         }
         
+        bool Program::hasConstant(std::string const& constantName) const {
+            return this->constantToIndexMap.find(constantName) != this->constantToIndexMap.end();
+        }
+        
+        Constant const& Program::getConstant(std::string const& constantName) const {
+            auto const& constantIndexPair = this->constantToIndexMap.find(constantName);
+            return this->getConstants()[constantIndexPair->second];
+        }
+        
         std::vector<Constant> const& Program::getConstants() const {
             return this->constants;
         }
@@ -158,7 +167,10 @@ namespace storm {
         }
         
         void Program::createMappings() {
-            // Build the mappings for global variables, formulas, modules, reward models and labels.
+            // Build the mappings for constants, global variables, formulas, modules, reward models and labels.
+            for (uint_fast64_t constantIndex = 0; constantIndex < this->getNumberOfConstants(); ++constantIndex) {
+                this->constantToIndexMap[this->getConstants()[constantIndex].getConstantName()] = constantIndex;
+            }
             for (uint_fast64_t globalVariableIndex = 0; globalVariableIndex < this->getNumberOfGlobalBooleanVariables(); ++globalVariableIndex) {
                 this->globalBooleanVariableToIndexMap[this->getGlobalBooleanVariables()[globalVariableIndex].getName()] = globalVariableIndex;
             }
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index cd3e62345..2c2e17b6f 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -65,6 +65,22 @@ namespace storm {
              */
             bool hasUndefinedConstants() const;
 
+            /*!
+             * Retrieves whether the given constant exists in the program.
+             *
+             * @param constantName The name of the constant to search.
+             * @return True iff the constant exists in the program.
+             */
+            bool hasConstant(std::string const& constantName) const;
+            
+            /*!
+             * Retrieves the constant with the given name if it exists.
+             *
+             * @param constantName The name of the constant to retrieve.
+             * @return The constant with the given name if it exists.
+             */
+            Constant const& getConstant(std::string const& constantName) const;
+            
             /*!
              * Retrieves all constants defined in the program.
              *
@@ -269,6 +285,9 @@ namespace storm {
             
             // The undefined constants of the program.
             std::vector<Constant> constants;
+            
+            // A mapping from constant names to their corresponding indices.
+            std::map<std::string, uint_fast64_t> constantToIndexMap;
 
             // The global boolean variables.
             std::vector<BooleanVariable> globalBooleanVariables;
diff --git a/src/utility/IRUtility.h b/src/utility/IRUtility.h
index a75f1972d..7efe08bbe 100644
--- a/src/utility/IRUtility.h
+++ b/src/utility/IRUtility.h
@@ -11,7 +11,7 @@
 #include <boost/algorithm/string.hpp>
 
 #include "src/storage/LabeledValues.h"
-#include "src/ir/IR.h"
+#include "src/storage/prism/Program.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
 #include "log4cplus/logger.h"

From 7667933caf6b72213a265f1ad49175b11d584f9d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 15 Apr 2014 23:59:43 +0200
Subject: [PATCH 073/147] First working version of explicit model generation
 using the new PRISM classes and expressions.

Former-commit-id: e71408cb890e464340c13aaca866c51138b180b3
---
 examples/dtmc/synchronous_leader/leader4_8.pm |   4 +-
 examples/dtmc/synchronous_leader/leader5_8.pm |   4 +-
 examples/dtmc/synchronous_leader/leader6_8.pm |   4 +-
 src/adapters/ExplicitModelAdapter.h           | 160 ++++--
 .../SMTMinimalCommandSetGenerator.h           |   2 +-
 src/storage/expressions/BaseExpression.cpp    |   6 +-
 src/storage/expressions/BaseExpression.h      |   6 +-
 .../BinaryBooleanFunctionExpression.cpp       |   2 +-
 .../BinaryBooleanFunctionExpression.h         |   2 +-
 .../BinaryNumericalFunctionExpression.cpp     |   4 +-
 .../BinaryNumericalFunctionExpression.h       |   4 +-
 .../expressions/BinaryRelationExpression.cpp  |   2 +-
 .../expressions/BinaryRelationExpression.h    |   2 +-
 .../expressions/BooleanConstantExpression.cpp |   6 +-
 .../expressions/BooleanConstantExpression.h   |   2 +-
 .../expressions/BooleanLiteralExpression.cpp  |   2 +-
 .../expressions/BooleanLiteralExpression.h    |   2 +-
 .../expressions/DoubleConstantExpression.cpp  |   6 +-
 .../expressions/DoubleConstantExpression.h    |   2 +-
 .../expressions/DoubleLiteralExpression.cpp   |   2 +-
 .../expressions/DoubleLiteralExpression.h     |   2 +-
 src/storage/expressions/Expression.cpp        |   6 +-
 src/storage/expressions/Expression.h          |   6 +-
 .../expressions/IfThenElseExpression.cpp      |   6 +-
 .../expressions/IfThenElseExpression.h        |   6 +-
 .../expressions/IntegerConstantExpression.cpp |  10 +-
 .../expressions/IntegerConstantExpression.h   |   4 +-
 .../expressions/IntegerLiteralExpression.cpp  |   6 +-
 .../expressions/IntegerLiteralExpression.h    |   4 +-
 src/storage/expressions/SimpleValuation.h     |   1 -
 .../UnaryBooleanFunctionExpression.cpp        |   2 +-
 .../UnaryBooleanFunctionExpression.h          |   2 +-
 .../UnaryNumericalFunctionExpression.cpp      |   4 +-
 .../UnaryNumericalFunctionExpression.h        |   4 +-
 .../expressions/VariableExpression.cpp        |  22 +-
 src/storage/expressions/VariableExpression.h  |   6 +-
 src/storage/prism/Program.cpp                 |  34 +-
 src/storage/prism/Program.h                   |   8 +
 src/storm.cpp                                 |   8 +-
 src/utility/IRUtility.h                       | 517 ------------------
 src/utility/PrismUtility.h                    | 195 +++++++
 41 files changed, 416 insertions(+), 661 deletions(-)
 delete mode 100644 src/utility/IRUtility.h
 create mode 100644 src/utility/PrismUtility.h

diff --git a/examples/dtmc/synchronous_leader/leader4_8.pm b/examples/dtmc/synchronous_leader/leader4_8.pm
index fc8f167a0..188039cf3 100644
--- a/examples/dtmc/synchronous_leader/leader4_8.pm
+++ b/examples/dtmc/synchronous_leader/leader4_8.pm
@@ -4,8 +4,8 @@
 dtmc
 
 // CONSTANTS
-const N = 4; // number of processes
-const K = 8; // range of probabilistic choice
+const int N = 4; // number of processes
+const int K = 8; // range of probabilistic choice
 
 // counter module used to count the number of processes that have been read
 // and to know when a process has decided
diff --git a/examples/dtmc/synchronous_leader/leader5_8.pm b/examples/dtmc/synchronous_leader/leader5_8.pm
index 72139fda9..4723ed5b0 100644
--- a/examples/dtmc/synchronous_leader/leader5_8.pm
+++ b/examples/dtmc/synchronous_leader/leader5_8.pm
@@ -4,8 +4,8 @@
 dtmc
 
 // CONSTANTS
-const N = 5; // number of processes
-const K = 8; // range of probabilistic choice
+const int N = 5; // number of processes
+const int K = 8; // range of probabilistic choice
 
 // counter module used to count the number of processes that have been read
 // and to know when a process has decided
diff --git a/examples/dtmc/synchronous_leader/leader6_8.pm b/examples/dtmc/synchronous_leader/leader6_8.pm
index 283042ad5..a31773b1d 100644
--- a/examples/dtmc/synchronous_leader/leader6_8.pm
+++ b/examples/dtmc/synchronous_leader/leader6_8.pm
@@ -4,8 +4,8 @@
 dtmc
 
 // CONSTANTS
-const N = 6; // number of processes
-const K = 8; // range of probabilistic choice
+const int N = 6; // number of processes
+const int K = 8; // range of probabilistic choice
 
 // counter module used to count the number of processes that have been read
 // and to know when a process has decided
diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index be293ebf6..0612f86e1 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -19,6 +19,7 @@
 
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/SimpleValuation.h"
+#include "src/utility/PrismUtility.h"
 #include "src/models/AbstractModel.h"
 #include "src/models/Dtmc.h"
 #include "src/models/Ctmc.h"
@@ -32,11 +33,16 @@
 
 namespace storm {
     namespace adapters {
+        
+        using namespace storm::utility::prism;
                 
         template<typename ValueType>
         class ExplicitModelAdapter {
         public:
             typedef storm::expressions::SimpleValuation StateType;
+            typedef storm::expressions::SimpleValuationPointerHash StateHash;
+            typedef storm::expressions::SimpleValuationPointerCompare StateCompare;
+            typedef storm::expressions::SimpleValuationPointerLess StateLess;
             
             // A structure holding information about the reachable state space.
             struct StateInformation {
@@ -47,8 +53,17 @@ namespace storm {
                 // A list of reachable states.
                 std::vector<StateType*> reachableStates;
                 
+                // A list of initial states.
+                std::vector<uint_fast64_t> initialStateIndices;
+                
                 // A mapping from states to indices in the list of reachable states.
-                std::unordered_map<StateType*, uint_fast64_t, storm::expressions::SimpleValuationPointerHash, storm::expressions::SimpleValuationPointerCompare> stateToIndexMap;
+                std::unordered_map<StateType*, uint_fast64_t, StateHash, StateCompare> stateToIndexMap;
+            };
+            
+            // A structure storing information about the used variables of the program.
+            struct VariableInformation {
+                // A mapping of (integer) variable to their lower/upper bounds.
+                std::map<std::string, std::pair<int_fast64_t, int_fast64_t>> variableToBoundsMap;
             };
             
             // A structure holding the individual components of a model.
@@ -146,10 +161,15 @@ namespace storm {
                 // First, we need to parse the constant definition string.
                 std::map<std::string, storm::expressions::Expression> constantDefinitions = parseConstantDefinitionString(program, constantDefinitionString);
                 
-                storm::prism::Program definedProgram = program.defineUndefinedConstants(constantDefinitions);
-                LOG_THROW(!definedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
+                storm::prism::Program preparedProgram = program.defineUndefinedConstants(constantDefinitions);
+                LOG_THROW(!preparedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
+                
+                // Now that we have defined all the constants in the program, we need to substitute their appearances in
+                // all expressions in the program so we can then evaluate them without having to store the values of the
+                // constants in the state (i.e., valuation).
+                preparedProgram = preparedProgram.substituteConstants();
                 
-                ModelComponents modelComponents = buildModelComponents(definedProgram, rewardModelName);
+                ModelComponents modelComponents = buildModelComponents(preparedProgram, rewardModelName);
                 
                 std::unique_ptr<storm::models::AbstractModel<ValueType>> result;
                 switch (program.getModelType()) {
@@ -183,8 +203,8 @@ namespace storm {
              * @params update The update to apply.
              * @return The resulting state.
              */
-            static StateType* applyUpdate(StateType const* state, storm::prism::Update const& update) {
-                return applyUpdate(state, state, update);
+            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::prism::Update const& update) {
+                return applyUpdate(variableInformation, state, state, update);
             }
             
             /*!
@@ -197,29 +217,23 @@ namespace storm {
              * @param update The update to apply.
              * @return The resulting state.
              */
-            static StateType* applyUpdate(StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
+            static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
                 StateType* newState = new StateType(*state);
+                
+                // This variable needs to be declared prior to the switch, because of C++ rules.
+                int_fast64_t newValue = 0;
                 for (auto const& assignment : update.getAssignments()) {
                     switch (assignment.getExpression().getReturnType()) {
-                        case storm::expressions::ExpressionReturnType::Bool: newState->setBooleanValue(assignment.getVariableName(), assignment.getExpression().evaluateAsBool(*baseState)); break;
+                        case storm::expressions::ExpressionReturnType::Bool: newState->setBooleanValue(assignment.getVariableName(), assignment.getExpression().evaluateAsBool(baseState)); break;
                         case storm::expressions::ExpressionReturnType::Int:
-                            int_fast64_t newValue = assignment.getExpression().evaluateAsInt(*baseState));
-                            newState->setIntegerValue(assignment.getVariableName(), assignment.getExpression().evaluateAsInt(*baseState)); break;
-                        default: LOG_ASSERT(false, "Invalid type of assignment.");
-                    }
-                }
-                for (auto variableAssignmentPair : update.getBooleanAssignments()) {
-                    setValue(newState, variableInformation.booleanVariableToIndexMap.at(variableAssignmentPair.first), variableAssignmentPair.second.getExpression()->getValueAsBool(baseState));
-                }
-                for (auto variableAssignmentPair : update.getIntegerAssignments()) {
-                    int_fast64_t newVariableValue = variableAssignmentPair.second.getExpression()->getValueAsInt(baseState);
-                    bool isLegalValueForVariable = newVariableValue >= variableInformation.lowerBounds.at(variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first)) && newVariableValue <= variableInformation.upperBounds.at(variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first));
-                    
-                    if (!isLegalValueForVariable) {
-                        throw storm::exceptions::InvalidStateException() << "Invalid value '" << newVariableValue << "' for variable \"" << variableInformation.integerVariables.at(variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first)).getName() << "\". Please strengthen the guards if necessary or enlarge the domains of the variables.";
+                        {
+                            newValue = assignment.getExpression().evaluateAsInt(baseState);
+                            auto const& boundsPair = variableInformation.variableToBoundsMap.find(assignment.getVariableName());
+                            LOG_THROW(boundsPair->second.first <= newValue && newValue <= boundsPair->second.second, storm::exceptions::InvalidArgumentException, "Invalid value " << newValue << " for variable '" << assignment.getVariableName() << "'.");
+                            newState->setIntegerValue(assignment.getVariableName(), newValue); break;
+                        }
+                        default: LOG_ASSERT(false, "Invalid type of assignment."); break;
                     }
-                    
-                    setValue(newState, variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first), newVariableValue);
                 }
                 return newState;
             }
@@ -278,7 +292,7 @@ namespace storm {
                         continue;
                     }
                     
-                    std::set<uint_fast64_t> const& commandIndices = module.getCommandsByAction(action);
+                    std::set<uint_fast64_t> const& commandIndices = module.getCommandIndicesByAction(action);
                     
                     // If the module contains the action, but there is no command in the module that is labeled with
                     // this action, we don't have any feasible command combinations.
@@ -291,7 +305,7 @@ namespace storm {
                     // Look up commands by their indices and add them if the guard evaluates to true in the given state.
                     for (uint_fast64_t commandIndex : commandIndices) {
                         storm::prism::Command const& command = module.getCommand(commandIndex);
-                        if (command.getGuard()->getValueAsBool(state)) {
+                        if (command.getGuardExpression().evaluateAsBool(state)) {
                             commands.push_back(command);
                         }
                     }
@@ -323,7 +337,7 @@ namespace storm {
                         // Only consider unlabeled commands.
                         if (command.getActionName() != "") continue;
                         // Skip the command, if it is not enabled.
-                        if (!command.getGuard()->getValueAsBool(currentState)) continue;
+                        if (!command.getGuardExpression().evaluateAsBool(currentState)) continue;
                         
                         result.push_back(Choice<ValueType>(""));
                         Choice<ValueType>& choice = result.back();
@@ -343,7 +357,7 @@ namespace storm {
                             }
                             
                             // Update the choice by adding the probability/target state to it.
-                            double probabilityToAdd = update.getLikelihoodExpression()->getValueAsDouble(currentState);
+                            double probabilityToAdd = update.getLikelihoodExpression().evaluateAsDouble(currentState);
                             probabilitySum += probabilityToAdd;
                             boost::container::flat_set<uint_fast64_t> labels;
 							labels.insert(update.getGlobalIndex());
@@ -351,10 +365,7 @@ namespace storm {
                         }
                         
                         // Check that the resulting distribution is in fact a distribution.
-                        if (std::abs(1 - probabilitySum) > storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) {
-                            LOG4CPLUS_ERROR(logger, "Sum of update probabilities should be one for command:\n\t"  << command.toString());
-                            throw storm::exceptions::WrongFormatException() << "Sum of update probabilities should be one for command:\n\t"  << command.toString();
-                        }
+                        LOG_THROW(std::abs(1 - probabilitySum) < storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble(), storm::exceptions::WrongFormatException, "Probabilities do not sum to one for command '" << command << "'.");
                     }
                 }
                 
@@ -398,7 +409,7 @@ namespace storm {
 
                                         storm::storage::LabeledValues<double> newProbability;
                                         
-                                        double updateProbability = update.getLikelihoodExpression()->getValueAsDouble(currentState);
+                                        double updateProbability = update.getLikelihoodExpression().evaluateAsDouble(currentState);
                                         for (auto const& valueLabelSetPair : stateProbabilityPair.second) {
                                             // Copy the label set, so we can modify it.
                                             boost::container::flat_set<uint_fast64_t> newLabelSet = valueLabelSetPair.second;
@@ -510,8 +521,36 @@ namespace storm {
                 
                 // Initialize a queue and insert the initial state.
                 std::queue<uint_fast64_t> stateQueue;
-                StateType* initialState = getInitialState(program, variableInformation);
-                getOrAddStateIndex(initialState, stateInformation);
+                uint_fast64_t numberOfBooleanVariables = program.getNumberOfGlobalBooleanVariables();
+                uint_fast64_t numberOfIntegerVariables = program.getNumberOfGlobalIntegerVariables();
+                for (auto const& module : program.getModules()) {
+                    numberOfBooleanVariables += module.getNumberOfBooleanVariables();
+                    numberOfIntegerVariables += module.getNumberOfIntegerVariables();
+                }
+                StateType* initialState = new StateType(numberOfBooleanVariables, numberOfIntegerVariables, 0);
+                uint_fast64_t booleanIndex = 0;
+                uint_fast64_t integerIndex = 0;
+                for (auto const& booleanVariable : program.getGlobalBooleanVariables()) {
+                    initialState->setIdentifierIndex(booleanVariable.getName(), booleanIndex++);
+                    initialState->setBooleanValue(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
+                }
+                for (auto const& integerVariable : program.getGlobalIntegerVariables()) {
+                    initialState->setIdentifierIndex(integerVariable.getName(), booleanIndex++);
+                    initialState->setIntegerValue(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
+                }
+                for (auto const& module : program.getModules()) {
+                    for (auto const& booleanVariable : module.getBooleanVariables()) {
+                        initialState->setIdentifierIndex(booleanVariable.getName(), booleanIndex++);
+                        initialState->setBooleanValue(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
+                    }
+                    for (auto const& integerVariable : module.getIntegerVariables()) {
+                        initialState->setIdentifierIndex(integerVariable.getName(), integerIndex++);
+                        initialState->setIntegerValue(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
+                    }
+                }
+        
+                std::pair<bool, uint_fast64_t> addIndexPair = getOrAddStateIndex(initialState, stateInformation);
+                stateInformation.initialStateIndices.push_back(addIndexPair.second);
                 stateQueue.push(stateInformation.stateToIndexMap[initialState]);
                 
                 // Now explore the current state until there is no more reachable state.
@@ -551,8 +590,8 @@ namespace storm {
                                     
                                     // Now add all rewards that match this choice.
                                     for (auto const& transitionReward : transitionRewards) {
-                                        if (transitionReward.getActionName() == "" && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
-                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
+                                        if (transitionReward.getActionName() == "" && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
+                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
                                         }
                                     }
                                 }
@@ -564,8 +603,8 @@ namespace storm {
                                 
                                     // Now add all rewards that match this choice.
                                     for (auto const& transitionReward : transitionRewards) {
-                                        if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
-                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
+                                        if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
+                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
                                         }
                                     }
                                 }
@@ -602,8 +641,8 @@ namespace storm {
                                     
                                     // Now add all rewards that match this choice.
                                     for (auto const& transitionReward : transitionRewards) {
-                                        if (transitionReward.getActionName() == "" && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
-                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
+                                        if (transitionReward.getActionName() == "" && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
+                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
                                         }
                                     }
 
@@ -629,8 +668,8 @@ namespace storm {
                                     
                                     // Now add all rewards that match this choice.
                                     for (auto const& transitionReward : transitionRewards) {
-                                        if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
-                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
+                                        if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
+                                            stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
                                         }
                                     }
 
@@ -665,7 +704,15 @@ namespace storm {
             static ModelComponents buildModelComponents(storm::prism::Program const& program, std::string const& rewardModelName) {
                 ModelComponents modelComponents;
                 
-                VariableInformation variableInformation = createVariableInformation(program);
+                VariableInformation variableInformation;
+                for (auto const& integerVariable : program.getGlobalIntegerVariables()) {
+                    variableInformation.variableToBoundsMap[integerVariable.getName()] = std::make_pair(integerVariable.getLowerBoundExpression().evaluateAsInt(), integerVariable.getUpperBoundExpression().evaluateAsInt());
+                }
+                for (auto const& module : program.getModules()) {
+                    for (auto const& integerVariable : module.getIntegerVariables()) {
+                        variableInformation.variableToBoundsMap[integerVariable.getName()] = std::make_pair(integerVariable.getLowerBoundExpression().evaluateAsInt(), integerVariable.getUpperBoundExpression().evaluateAsInt());
+                    }
+                }
                 
                 // Create the structure for storing the reachable state space.
                 StateInformation stateInformation;
@@ -675,7 +722,7 @@ namespace storm {
                 
                 // Determine whether we have to combine different choices to one or whether this model can have more than
                 // one choice per state.
-                bool deterministicModel = program.getModelType() == storm::prism::Program::DTMC || program.getModelType() == storm::prism::Program::CTMC;
+                bool deterministicModel = program.getModelType() == storm::prism::Program::ModelType::DTMC || program.getModelType() == storm::prism::Program::ModelType::CTMC;
 
                 // Build the transition and reward matrices.
                 storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, 0, 0, !deterministicModel, 0);
@@ -709,29 +756,28 @@ namespace storm {
              * @return The state labeling of the given program.
              */
             static storm::models::AtomicPropositionsLabeling buildStateLabeling(storm::prism::Program const& program, VariableInformation const& variableInformation, StateInformation const& stateInformation) {
-                std::map<std::string, std::unique_ptr<storm::prism::expressions::BaseExpression>> const& labels = program.getLabels();
+                std::vector<storm::prism::Label> const& labels = program.getLabels();
                 
                 storm::models::AtomicPropositionsLabeling result(stateInformation.reachableStates.size(), labels.size() + 1);
                 
                 // Initialize labeling.
-                for (auto const& labelExpressionPair : labels) {
-                    result.addAtomicProposition(labelExpressionPair.first);
+                for (auto const& label : labels) {
+                    result.addAtomicProposition(label.getLabelName());
                 }
                 for (uint_fast64_t index = 0; index < stateInformation.reachableStates.size(); index++) {
-                    for (auto const& labelExpressionPair: labels) {
+                    for (auto const& label : labels) {
                         // Add label to state, if the corresponding expression is true.
-                        if (labelExpressionPair.second->getValueAsBool(stateInformation.reachableStates[index])) {
-                            result.addAtomicPropositionToState(labelExpressionPair.first, index);
+                        if (label.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates[index])) {
+                            result.addAtomicPropositionToState(label.getLabelName(), index);
                         }
                     }
                 }
                 
                 // Also label the initial state with the special label "init".
                 result.addAtomicProposition("init");
-                StateType* initialState = getInitialState(program, variableInformation);
-                uint_fast64_t initialIndex = stateInformation.stateToIndexMap.at(initialState);
-                result.addAtomicPropositionToState("init", initialIndex);
-                delete initialState;
+                for (auto const& index : stateInformation.initialStateIndices) {
+                    result.addAtomicPropositionToState("init", index);
+                }
                 
                 return result;
             }
@@ -749,8 +795,8 @@ namespace storm {
                     result[index] = ValueType(0);
                     for (auto const& reward : rewards) {
                         // Add this reward to the state if the state is included in the state reward.
-                        if (reward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates[index])) {
-                            result[index] += ValueType(reward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates[index]));
+                        if (reward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates[index])) {
+                            result[index] += ValueType(reward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates[index]));
                         }
                     }
                 }
diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h
index f95bc2806..da5d4a7ad 100644
--- a/src/counterexamples/SMTMinimalCommandSetGenerator.h
+++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h
@@ -25,7 +25,7 @@
 #include "src/solver/GmmxxNondeterministicLinearEquationSolver.h"
 
 #include "src/utility/counterexamples.h"
-#include "src/utility/IRUtility.h"
+#include "src/utility/PrismUtility.h"
 
 namespace storm {
     namespace counterexamples {
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index f66cd7dc3..b9734a9ad 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -24,15 +24,15 @@ namespace storm {
             return this->getReturnType() == ExpressionReturnType::Bool;
         }
         
-        int_fast64_t BaseExpression::evaluateAsInt(Valuation const& evaluation) const {
+        int_fast64_t BaseExpression::evaluateAsInt(Valuation const* valuation) const {
             LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
         }
         
-        bool BaseExpression::evaluateAsBool(Valuation const& evaluation) const {
+        bool BaseExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
         }
         
-        double BaseExpression::evaluateAsDouble(Valuation const& evaluation) const {
+        double BaseExpression::evaluateAsDouble(Valuation const* valuation) const {
             LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
         }
         
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 4039209d3..41684255d 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -48,7 +48,7 @@ namespace storm {
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The boolean value of the expression under the given valuation.
              */
-            virtual bool evaluateAsBool(Valuation const& valuation) const;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const;
 
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
@@ -58,7 +58,7 @@ namespace storm {
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The integer value of the expression under the given valuation.
              */
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const;
             
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
@@ -68,7 +68,7 @@ namespace storm {
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The double value of the expression under the given valuation.
              */
-            virtual double evaluateAsDouble(Valuation const& valuation) const;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const;
 
             /*!
              * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants.
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index 8cc30aa19..9f5e5edeb 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -13,7 +13,7 @@ namespace storm {
             return this->operatorType;
         }
         
-        bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
+        bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
             
             bool firstOperandEvaluation = this->getFirstOperand()->evaluateAsBool(valuation);
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index b4f8ad0a6..32dfc387d 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -30,7 +30,7 @@ namespace storm {
             virtual ~BinaryBooleanFunctionExpression() = default;
             
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
 
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
index 521e554bb..225bea963 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -14,7 +14,7 @@ namespace storm {
             return this->operatorType;
         }
         
-        int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
+        int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const* valuation) const {
             LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
             
             int_fast64_t firstOperandEvaluation = this->getFirstOperand()->evaluateAsInt(valuation);
@@ -29,7 +29,7 @@ namespace storm {
             }
         }
         
-        double BinaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
+        double BinaryNumericalFunctionExpression::evaluateAsDouble(Valuation const* valuation) const {
             LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
             
             double firstOperandEvaluation = this->getFirstOperand()->evaluateAsDouble(valuation);
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
index 8d49e541a..174763c84 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -30,8 +30,8 @@ namespace storm {
             virtual ~BinaryNumericalFunctionExpression() = default;
             
             // Override base class methods.
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
 
diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp
index e23df77c4..1b00485b6 100644
--- a/src/storage/expressions/BinaryRelationExpression.cpp
+++ b/src/storage/expressions/BinaryRelationExpression.cpp
@@ -9,7 +9,7 @@ namespace storm {
             // Intentionally left empty.
         }
                 
-        bool BinaryRelationExpression::evaluateAsBool(Valuation const& valuation) const {
+        bool BinaryRelationExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
 
             double firstOperandEvaluated = this->getFirstOperand()->evaluateAsDouble(valuation);
diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h
index 70201313c..7e3e177c5 100644
--- a/src/storage/expressions/BinaryRelationExpression.h
+++ b/src/storage/expressions/BinaryRelationExpression.h
@@ -30,7 +30,7 @@ namespace storm {
             virtual ~BinaryRelationExpression() = default;
             
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
 
diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp
index b3b453097..de87dab48 100644
--- a/src/storage/expressions/BooleanConstantExpression.cpp
+++ b/src/storage/expressions/BooleanConstantExpression.cpp
@@ -1,4 +1,5 @@
 #include "src/storage/expressions/BooleanConstantExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
     namespace expressions {
@@ -6,8 +7,9 @@ namespace storm {
             // Intentionally left empty.
         }
                 
-        bool BooleanConstantExpression::evaluateAsBool(Valuation const& valuation) const {
-            return valuation.getBooleanValue(this->getConstantName());
+        bool BooleanConstantExpression::evaluateAsBool(Valuation const* valuation) const {
+            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
+            return valuation->getBooleanValue(this->getConstantName());
         }
         
         void BooleanConstantExpression::accept(ExpressionVisitor* visitor) const {
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
index d239f146d..fc2e3f8e4 100644
--- a/src/storage/expressions/BooleanConstantExpression.h
+++ b/src/storage/expressions/BooleanConstantExpression.h
@@ -22,7 +22,7 @@ namespace storm {
             virtual ~BooleanConstantExpression() = default;
             
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
         };
diff --git a/src/storage/expressions/BooleanLiteralExpression.cpp b/src/storage/expressions/BooleanLiteralExpression.cpp
index 7fb01cec4..6ef15fe83 100644
--- a/src/storage/expressions/BooleanLiteralExpression.cpp
+++ b/src/storage/expressions/BooleanLiteralExpression.cpp
@@ -6,7 +6,7 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        bool BooleanLiteralExpression::evaluateAsBool(Valuation const& valuation) const {
+        bool BooleanLiteralExpression::evaluateAsBool(Valuation const* valuation) const {
             return this->getValue();
         }
         
diff --git a/src/storage/expressions/BooleanLiteralExpression.h b/src/storage/expressions/BooleanLiteralExpression.h
index 1c7baed09..49794b59a 100644
--- a/src/storage/expressions/BooleanLiteralExpression.h
+++ b/src/storage/expressions/BooleanLiteralExpression.h
@@ -22,7 +22,7 @@ namespace storm {
             virtual ~BooleanLiteralExpression() = default;
 
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual bool isConstant() const override;
             virtual bool isTrue() const override;
             virtual bool isFalse() const override;
diff --git a/src/storage/expressions/DoubleConstantExpression.cpp b/src/storage/expressions/DoubleConstantExpression.cpp
index d0f5a2799..e7d541975 100644
--- a/src/storage/expressions/DoubleConstantExpression.cpp
+++ b/src/storage/expressions/DoubleConstantExpression.cpp
@@ -1,4 +1,5 @@
 #include "src/storage/expressions/DoubleConstantExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
     namespace expressions {
@@ -6,8 +7,9 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        double DoubleConstantExpression::evaluateAsDouble(Valuation const& valuation) const {
-            return valuation.getDoubleValue(this->getConstantName());
+        double DoubleConstantExpression::evaluateAsDouble(Valuation const* valuation) const {
+            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
+            return valuation->getDoubleValue(this->getConstantName());
         }
         
         std::shared_ptr<BaseExpression const> DoubleConstantExpression::simplify() const {
diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h
index 349de5216..673ef007b 100644
--- a/src/storage/expressions/DoubleConstantExpression.h
+++ b/src/storage/expressions/DoubleConstantExpression.h
@@ -22,7 +22,7 @@ namespace storm {
             virtual ~DoubleConstantExpression() = default;
             
             // Override base class methods.
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
         };
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index 176823803..642a1817f 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -6,7 +6,7 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        double DoubleLiteralExpression::evaluateAsDouble(Valuation const& valuation) const {
+        double DoubleLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
             return this->getValue();
         }
         
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index 5d97e6b59..1ed293923 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -22,7 +22,7 @@ namespace storm {
             virtual ~DoubleLiteralExpression() = default;
             
             // Override base class methods.
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual bool isConstant() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 7da4f8b37..7eb94966b 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -37,15 +37,15 @@ namespace storm {
             return IdentifierSubstitutionVisitor<MapType>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
         }
         
-        bool Expression::evaluateAsBool(Valuation const& valuation) const {
+        bool Expression::evaluateAsBool(Valuation const* valuation) const {
             return this->getBaseExpression().evaluateAsBool(valuation);
         }
         
-        int_fast64_t Expression::evaluateAsInt(Valuation const& valuation) const {
+        int_fast64_t Expression::evaluateAsInt(Valuation const* valuation) const {
             return this->getBaseExpression().evaluateAsInt(valuation);
         }
         
-        double Expression::evaluateAsDouble(Valuation const& valuation) const {
+        double Expression::evaluateAsDouble(Valuation const* valuation) const {
             return this->getBaseExpression().evaluateAsDouble(valuation);
         }
         
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 96f8ce6fd..2253c0548 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -94,7 +94,7 @@ namespace storm {
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The boolean value of the expression under the given valuation.
              */
-            bool evaluateAsBool(Valuation const& valuation) const;
+            bool evaluateAsBool(Valuation const* valuation = nullptr) const;
             
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
@@ -104,7 +104,7 @@ namespace storm {
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The integer value of the expression under the given valuation.
              */
-            int_fast64_t evaluateAsInt(Valuation const& valuation) const;
+            int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const;
             
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
@@ -114,7 +114,7 @@ namespace storm {
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The double value of the expression under the given valuation.
              */
-            double evaluateAsDouble(Valuation const& valuation) const;
+            double evaluateAsDouble(Valuation const* valuation = nullptr) const;
             
             /*!
              * Simplifies the expression according to some basic rules.
diff --git a/src/storage/expressions/IfThenElseExpression.cpp b/src/storage/expressions/IfThenElseExpression.cpp
index dffee088d..81ebca670 100644
--- a/src/storage/expressions/IfThenElseExpression.cpp
+++ b/src/storage/expressions/IfThenElseExpression.cpp
@@ -6,7 +6,7 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        bool IfThenElseExpression::evaluateAsBool(Valuation const& valuation) const {
+        bool IfThenElseExpression::evaluateAsBool(Valuation const* valuation) const {
             bool conditionValue = this->condition->evaluateAsBool(valuation);
             if (conditionValue) {
                 return this->thenExpression->evaluateAsBool(valuation);
@@ -15,7 +15,7 @@ namespace storm {
             }
         }
         
-        int_fast64_t IfThenElseExpression::evaluateAsInt(Valuation const& valuation) const {
+        int_fast64_t IfThenElseExpression::evaluateAsInt(Valuation const* valuation) const {
             bool conditionValue = this->condition->evaluateAsBool(valuation);
             if (conditionValue) {
                 return this->thenExpression->evaluateAsInt(valuation);
@@ -24,7 +24,7 @@ namespace storm {
             }
         }
         
-        double IfThenElseExpression::evaluateAsDouble(Valuation const& valuation) const {
+        double IfThenElseExpression::evaluateAsDouble(Valuation const* valuation) const {
             bool conditionValue = this->condition->evaluateAsBool(valuation);
             if (conditionValue) {
                 return this->thenExpression->evaluateAsDouble(valuation);
diff --git a/src/storage/expressions/IfThenElseExpression.h b/src/storage/expressions/IfThenElseExpression.h
index 794a75bee..1f8e2db41 100644
--- a/src/storage/expressions/IfThenElseExpression.h
+++ b/src/storage/expressions/IfThenElseExpression.h
@@ -24,9 +24,9 @@ namespace storm {
             virtual ~IfThenElseExpression() = default;
             
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual bool isConstant() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
diff --git a/src/storage/expressions/IntegerConstantExpression.cpp b/src/storage/expressions/IntegerConstantExpression.cpp
index 92bedebc9..60ad8de89 100644
--- a/src/storage/expressions/IntegerConstantExpression.cpp
+++ b/src/storage/expressions/IntegerConstantExpression.cpp
@@ -1,4 +1,5 @@
 #include "src/storage/expressions/IntegerConstantExpression.h"
+#include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
     namespace expressions {
@@ -6,12 +7,13 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        int_fast64_t IntegerConstantExpression::evaluateAsInt(Valuation const& valuation) const {
-            return valuation.getIntegerValue(this->getConstantName());
+        int_fast64_t IntegerConstantExpression::evaluateAsInt(Valuation const* valuation) const {
+            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
+            return valuation->getIntegerValue(this->getConstantName());
         }
         
-        double IntegerConstantExpression::evaluateAsDouble(Valuation const& valuation) const {
-            return static_cast<double>(valuation.getIntegerValue(this->getConstantName()));
+        double IntegerConstantExpression::evaluateAsDouble(Valuation const* valuation) const {
+            return static_cast<double>(this->evaluateAsInt(valuation));
         }
         
         std::shared_ptr<BaseExpression const> IntegerConstantExpression::simplify() const {
diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h
index 05deaf49c..6a808b215 100644
--- a/src/storage/expressions/IntegerConstantExpression.h
+++ b/src/storage/expressions/IntegerConstantExpression.h
@@ -22,8 +22,8 @@ namespace storm {
             virtual ~IntegerConstantExpression() = default;
             
             // Override base class methods.
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const;
         };
diff --git a/src/storage/expressions/IntegerLiteralExpression.cpp b/src/storage/expressions/IntegerLiteralExpression.cpp
index 16adeadc6..5e6404fc8 100644
--- a/src/storage/expressions/IntegerLiteralExpression.cpp
+++ b/src/storage/expressions/IntegerLiteralExpression.cpp
@@ -6,12 +6,12 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        int_fast64_t IntegerLiteralExpression::evaluateAsInt(Valuation const& valuation) const {
+        int_fast64_t IntegerLiteralExpression::evaluateAsInt(Valuation const* valuation) const {
             return this->getValue();
         }
         
-        double IntegerLiteralExpression::evaluateAsDouble(Valuation const& valuation) const {
-            return static_cast<double>(this->getValue());
+        double IntegerLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
+            return static_cast<double>(this->evaluateAsInt(valuation));
         }
         
         bool IntegerLiteralExpression::isConstant() const {
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
index 1b71ea306..6cbce6e17 100644
--- a/src/storage/expressions/IntegerLiteralExpression.h
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -22,8 +22,8 @@ namespace storm {
             virtual ~IntegerLiteralExpression() = default;
             
             // Override base class methods.
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual bool isConstant() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 0c2231a63..16719be00 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -37,7 +37,6 @@ namespace storm {
             SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues);
 
             // Instantiate some constructors and assignments with their default implementations.
-            SimpleValuation() = default;
             SimpleValuation(SimpleValuation const&) = default;
             SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
index 0b12b5bf6..7e405bb29 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
@@ -13,7 +13,7 @@ namespace storm {
             return this->operatorType;
         }
         
-        bool UnaryBooleanFunctionExpression::evaluateAsBool(Valuation const& valuation) const {
+        bool UnaryBooleanFunctionExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
 
             bool operandEvaluated = this->getOperand()->evaluateAsBool(valuation);
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h
index fefbded86..954d3659d 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h
@@ -29,7 +29,7 @@ namespace storm {
             virtual ~UnaryBooleanFunctionExpression() = default;
             
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
 
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
index 31f9aeb1e..02a4bee30 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
@@ -14,7 +14,7 @@ namespace storm {
             return this->operatorType;
         }
         
-        int_fast64_t UnaryNumericalFunctionExpression::evaluateAsInt(Valuation const& valuation) const {
+        int_fast64_t UnaryNumericalFunctionExpression::evaluateAsInt(Valuation const* valuation) const {
             LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
 
             int_fast64_t operandEvaluated = this->getOperand()->evaluateAsInt(valuation);
@@ -25,7 +25,7 @@ namespace storm {
             }
         }
         
-        double UnaryNumericalFunctionExpression::evaluateAsDouble(Valuation const& valuation) const {
+        double UnaryNumericalFunctionExpression::evaluateAsDouble(Valuation const* valuation) const {
             LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
 
             double operandEvaluated = this->getOperand()->evaluateAsDouble(valuation);
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h
index 2f50549ef..be717e564 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h
@@ -29,8 +29,8 @@ namespace storm {
             virtual ~UnaryNumericalFunctionExpression() = default;
             
             // Override base class methods.
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
      
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
index b7a6ce6d2..d7765f14a 100644
--- a/src/storage/expressions/VariableExpression.cpp
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -12,27 +12,33 @@ namespace storm {
             return this->variableName;
         }
         
-        bool VariableExpression::evaluateAsBool(Valuation const& evaluation) const {
+        bool VariableExpression::evaluateAsBool(Valuation const* valuation) const {
+            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Cannot evaluate expression as boolean: return type is not a boolean.");
             
-            return evaluation.getBooleanValue(this->getVariableName());
+            return valuation->getBooleanValue(this->getVariableName());
         }
 
-        int_fast64_t VariableExpression::evaluateAsInt(Valuation const& evaluation) const {
+        int_fast64_t VariableExpression::evaluateAsInt(Valuation const* valuation) const {
+            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
             LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Cannot evaluate expression as integer: return type is not an integer.");
             
-            return evaluation.getIntegerValue(this->getVariableName());
+            return valuation->getIntegerValue(this->getVariableName());
         }
         
-        double VariableExpression::evaluateAsDouble(Valuation const& evaluation) const {
+        double VariableExpression::evaluateAsDouble(Valuation const* valuation) const {
+            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
             LOG_THROW(this->hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Cannot evaluate expression as double: return type is not a double.");
             
             switch (this->getReturnType()) {
-                case ExpressionReturnType::Int: return static_cast<double>(evaluation.getIntegerValue(this->getVariableName())); break;
-                case ExpressionReturnType::Double: evaluation.getDoubleValue(this->getVariableName()); break;
+                case ExpressionReturnType::Int: return static_cast<double>(valuation->getIntegerValue(this->getVariableName())); break;
+                case ExpressionReturnType::Double: valuation->getDoubleValue(this->getVariableName()); break;
                 default: break;
             }
-            LOG_THROW(false, storm::exceptions::InvalidTypeException, "Type of variable is required to be numeric.");
+            LOG_ASSERT(false, "Type of variable is required to be numeric.");
+            
+            // Silence warning. This point can never be reached.
+            return 0;
         }
         
         std::set<std::string> VariableExpression::getVariables() const {
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index 7e4732eda..1b86274a9 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -23,9 +23,9 @@ namespace storm {
             virtual ~VariableExpression() = default;
 
             // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const& valuation) const override;
-            virtual int_fast64_t evaluateAsInt(Valuation const& valuation) const override;
-            virtual double evaluateAsDouble(Valuation const& valuation) const override;
+            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
+            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index c635cbf63..49ebd7724 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -19,7 +19,7 @@ namespace storm {
                     return true;
                 }
             }
-            return true;
+            return false;
         }
         
         bool Program::hasConstant(std::string const& constantName) const {
@@ -255,46 +255,58 @@ namespace storm {
                 LOG_THROW(definedUndefinedConstants.find(constantExpressionPair.first) != definedUndefinedConstants.end(), storm::exceptions::InvalidArgumentException, "Unable to define non-existant constant.");
             }
             
+            return Program(this->getModelType(), newConstants, this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), this->getModules(), this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+        }
+        
+        Program Program::substituteConstants() const {
+            // We start by creating the appropriate substitution
+            std::map<std::string, storm::expressions::Expression> constantSubstitution;
+            for (auto const& constant : this->getConstants()) {
+                LOG_THROW(constant.isDefined(), storm::exceptions::InvalidArgumentException, "Cannot substitute constants in program that contains undefined constants.");
+                
+                constantSubstitution.emplace(constant.getConstantName(), constant.getExpression());
+            }
+            
             // Now we can substitute the constants in all expressions appearing in the program.
             std::vector<BooleanVariable> newBooleanVariables;
             newBooleanVariables.reserve(this->getNumberOfGlobalBooleanVariables());
             for (auto const& booleanVariable : this->getGlobalBooleanVariables()) {
-                newBooleanVariables.emplace_back(booleanVariable.substitute(constantDefinitions));
+                newBooleanVariables.emplace_back(booleanVariable.substitute(constantSubstitution));
             }
             
             std::vector<IntegerVariable> newIntegerVariables;
             newBooleanVariables.reserve(this->getNumberOfGlobalIntegerVariables());
             for (auto const& integerVariable : this->getGlobalIntegerVariables()) {
-                newIntegerVariables.emplace_back(integerVariable.substitute(constantDefinitions));
+                newIntegerVariables.emplace_back(integerVariable.substitute(constantSubstitution));
             }
-        
+            
             std::vector<Formula> newFormulas;
             newFormulas.reserve(this->getNumberOfFormulas());
             for (auto const& formula : this->getFormulas()) {
-                newFormulas.emplace_back(formula.substitute(constantDefinitions));
+                newFormulas.emplace_back(formula.substitute(constantSubstitution));
             }
-
+            
             std::vector<Module> newModules;
             newModules.reserve(this->getNumberOfModules());
             for (auto const& module : this->getModules()) {
-                newModules.emplace_back(module.substitute(constantDefinitions));
+                newModules.emplace_back(module.substitute(constantSubstitution));
             }
             
             std::vector<RewardModel> newRewardModels;
             newRewardModels.reserve(this->getNumberOfRewardModels());
             for (auto const& rewardModel : this->getRewardModels()) {
-                newRewardModels.emplace_back(rewardModel.substitute(constantDefinitions));
+                newRewardModels.emplace_back(rewardModel.substitute(constantSubstitution));
             }
             
-            storm::expressions::Expression newInitialStateExpression = this->getInitialStatesExpression().substitute<std::map>(constantDefinitions);
+            storm::expressions::Expression newInitialStateExpression = this->getInitialStatesExpression().substitute<std::map>(constantSubstitution);
             
             std::vector<Label> newLabels;
             newLabels.reserve(this->getNumberOfLabels());
             for (auto const& label : this->getLabels()) {
-                newLabels.emplace_back(label.substitute(constantDefinitions));
+                newLabels.emplace_back(label.substitute(constantSubstitution));
             }
             
-            return Program(this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
+            return Program(this->getModelType(), std::vector<Constant>(), newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
         }
         
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 2c2e17b6f..6f4c5e3b1 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -274,6 +274,14 @@ namespace storm {
              */
             Program defineUndefinedConstants(std::map<std::string, storm::expressions::Expression> const& constantDefinitions) const;
             
+            /*!
+             * Substitutes all constants appearing in the expressions of the program by their defining expressions. For
+             * this to work, all constants need to be defined prior to calling this.
+             *
+             * @return The resulting program that only contains expressions over variables of the program.
+             */
+            Program substituteConstants() const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Program const& program);
             
         private:
diff --git a/src/storm.cpp b/src/storm.cpp
index 16fa59806..c7b40247a 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -34,7 +34,7 @@
 #include "src/solver/GmmxxNondeterministicLinearEquationSolver.h"
 #include "src/solver/GurobiLpSolver.h"
 #include "src/counterexamples/MILPMinimalLabelSetGenerator.h"
-#include "src/counterexamples/SMTMinimalCommandSetGenerator.h"
+// #include "src/counterexamples/SMTMinimalCommandSetGenerator.h"
 #include "src/counterexamples/PathBasedSubsystemGenerator.h"
 #include "src/parser/AutoParser.h"
 #include "src/parser/MarkovAutomatonParser.h"
@@ -58,7 +58,7 @@ log4cplus::Logger logger;
 
 #include "src/parser/PrismParser.h"
 #include "src/adapters/ExplicitModelAdapter.h"
-#include "src/adapters/SymbolicModelAdapter.h"
+// #include "src/adapters/SymbolicModelAdapter.h"
 
 #include "src/exceptions/InvalidSettingsException.h"
 
@@ -534,7 +534,7 @@ int main(const int argc, const char* argv[]) {
             // First, we build the model using the given symbolic model description and constant definitions.
             std::string const& programFile = s->getOptionByLongName("symbolic").getArgument(0).getValueAsString();
             std::string const& constants = s->getOptionByLongName("constants").getArgument(0).getValueAsString();
-            storm::ir::Program program = storm::parser::PrismParserFromFile(programFile);
+            storm::prism::Program program = storm::parser::PrismParser::parse(programFile);
             std::shared_ptr<storm::models::AbstractModel<double>> model = storm::adapters::ExplicitModelAdapter<double>::translateProgram(program, constants);
             model->printModelInformationToStream(std::cout);
             
@@ -558,7 +558,7 @@ int main(const int argc, const char* argv[]) {
                     if (useMILP) {
                         storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(program, *mdp, formulaPtr);
                     } else {
-                        storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr);
+                        // storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr);
                     }
                     
                     // Once we are done with the formula, delete it.
diff --git a/src/utility/IRUtility.h b/src/utility/IRUtility.h
deleted file mode 100644
index 7efe08bbe..000000000
--- a/src/utility/IRUtility.h
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * IRUtility.h
- *
- *  Created on: 05.10.2013
- *      Author: Christian Dehnert
- */
-
-#ifndef STORM_UTILITY_IRUTILITY_H_
-#define STORM_UTILITY_IRUTILITY_H_
-
-#include <boost/algorithm/string.hpp>
-
-#include "src/storage/LabeledValues.h"
-#include "src/storage/prism/Program.h"
-#include "src/exceptions/InvalidArgumentException.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-
-extern log4cplus::Logger logger;
-
-namespace storm {
-    namespace utility {
-        namespace ir {
-
-            /*!
-             * A state of the model, i.e. a valuation of all variables.
-             */
-            typedef std::pair<std::vector<bool>, std::vector<int_fast64_t>> StateType;
-            
-            /*!
-             * A helper class that provides the functionality to compute a hash value for states of the model.
-             */
-            class StateHash {
-            public:
-                std::size_t operator()(StateType* state) const {
-                    size_t seed = 0;
-                    for (auto it : state->first) {
-                        boost::hash_combine<bool>(seed, it);
-                    }
-                    for (auto it : state->second) {
-                        boost::hash_combine<int_fast64_t>(seed, it);
-                    }
-                    return seed;
-                }
-            };
-            
-            /*!
-             * A helper class that provides the functionality to compare states of the model wrt. equality.
-             */
-            class StateCompare {
-            public:
-                bool operator()(StateType* state1, StateType* state2) const {
-                    return *state1 == *state2;
-                }
-            };
-            
-            /*!
-             * A helper class that provides the functionality to compare states of the model wrt. the relation "<".
-             */
-            class StateLess {
-            public:
-                bool operator()(StateType* state1, StateType* state2) const {
-                    // Compare boolean variables.
-                    for (uint_fast64_t i = 0; i < state1->first.size(); ++i) {
-                        if (!state1->first.at(i) && state2->first.at(i)) {
-                            return true;
-                        }
-                    }
-                    // Then compare integer variables.
-                    for (uint_fast64_t i = 0; i < state1->second.size(); ++i) {
-                        if (!state1->second.at(i) && state2->second.at(i)) {
-                            return true;
-                        }
-                    }
-                    return false;
-                }
-            };
-            
-            // A structure holding information about a particular choice.
-            template<typename ValueType, typename KeyType=uint_fast64_t, typename Compare=std::less<uint_fast64_t>>
-            struct Choice {
-            public:
-                Choice(std::string const& actionLabel) : distribution(), actionLabel(actionLabel), choiceLabels() {
-                    // Intentionally left empty.
-                }
-                
-                /*!
-                 * Returns an iterator to the first element of this choice.
-                 *
-                 * @return An iterator to the first element of this choice.
-                 */
-                typename std::map<KeyType, ValueType>::iterator begin() {
-                    return distribution.begin();
-                }
-                
-                /*!
-                 * Returns an iterator to the first element of this choice.
-                 *
-                 * @return An iterator to the first element of this choice.
-                 */
-                typename std::map<KeyType, ValueType>::const_iterator begin() const {
-                    return distribution.cbegin();
-                }
-                
-                /*!
-                 * Returns an iterator that points past the elements of this choice.
-                 *
-                 * @return An iterator that points past the elements of this choice.
-                 */
-                typename std::map<KeyType, ValueType>::iterator end() {
-                    return distribution.end();
-                }
-                
-                /*!
-                 * Returns an iterator that points past the elements of this choice.
-                 *
-                 * @return An iterator that points past the elements of this choice.
-                 */
-                typename std::map<KeyType, ValueType>::const_iterator end() const {
-                    return distribution.cend();
-                }
-                
-                /*!
-                 * Returns an iterator to the element with the given key, if there is one. Otherwise, the iterator points to
-                 * distribution.end().
-                 *
-                 * @param value The value to find.
-                 * @return An iterator to the element with the given key, if there is one.
-                 */
-                typename std::map<KeyType, ValueType>::iterator find(uint_fast64_t value) {
-                    return distribution.find(value);
-                }
-                
-                /*!
-                 * Inserts the contents of this object to the given output stream.
-                 *
-                 * @param out The stream in which to insert the contents.
-                 */
-                friend std::ostream& operator<<(std::ostream& out, Choice<ValueType> const& choice) {
-                    out << "<";
-                    for (auto const& stateProbabilityPair : choice.distribution) {
-                        out << stateProbabilityPair.first << " : " << stateProbabilityPair.second << ", ";
-                    }
-                    out << ">";
-                    return out;
-                }
-                
-                /*!
-                 * Adds the given label to the labels associated with this choice.
-                 *
-                 * @param label The label to associate with this choice.
-                 */
-                void addChoiceLabel(uint_fast64_t label) {
-                    choiceLabels.insert(label);
-                }
-                
-                /*!
-                 * Adds the given label set to the labels associated with this choice.
-                 *
-                 * @param labelSet The label set to associate with this choice.
-                 */
-                void addChoiceLabels(boost::container::flat_set<uint_fast64_t> const& labelSet) {
-                    for (uint_fast64_t label : labelSet) {
-                        addChoiceLabel(label);
-                    }
-                }
-                
-                /*!
-                 * Retrieves the set of labels associated with this choice.
-                 *
-                 * @return The set of labels associated with this choice.
-                 */
-                boost::container::flat_set<uint_fast64_t> const& getChoiceLabels() const {
-                    return choiceLabels;
-                }
-                
-                /*!
-                 * Retrieves the action label of this choice.
-                 *
-                 * @return The action label of this choice.
-                 */
-                std::string const& getActionLabel() const {
-                    return actionLabel;
-                }
-                
-                /*!
-                 * Retrieves the entry in the choice that is associated with the given state and creates one if none exists,
-                 * yet.
-                 *
-                 * @param state The state for which to add the entry.
-                 * @return A reference to the entry that is associated with the given state.
-                 */
-                ValueType& getOrAddEntry(uint_fast64_t state) {
-                    auto stateProbabilityPair = distribution.find(state);
-                    
-                    if (stateProbabilityPair == distribution.end()) {
-                        distribution[state] = ValueType();
-                    }
-                    return distribution.at(state);
-                }
-                
-                /*!
-                 * Retrieves the entry in the choice that is associated with the given state and creates one if none exists,
-                 * yet.
-                 *
-                 * @param state The state for which to add the entry.
-                 * @return A reference to the entry that is associated with the given state.
-                 */
-                ValueType const& getOrAddEntry(uint_fast64_t state) const {
-                    auto stateProbabilityPair = distribution.find(state);
-                    
-                    if (stateProbabilityPair == distribution.end()) {
-                        distribution[state] = ValueType();
-                    }
-                    return distribution.at(state);
-                }
-                
-            private:
-                // The distribution that is associated with the choice.
-                std::map<KeyType, ValueType, Compare> distribution;
-                
-                // The label of the choice.
-                std::string actionLabel;
-                
-                // The labels that are associated with this choice.
-                boost::container::flat_set<uint_fast64_t> choiceLabels;
-            };
-            
-            /*!
-             * Adds the target state and probability to the given choice and ignores the labels. This function overloads with
-             * other functions to ensure the proper treatment of labels.
-             *
-             * @param choice The choice to which to add the target state and probability.
-             * @param state The target state of the probability.
-             * @param probability The probability to reach the target state in one step.
-             * @param labels A set of labels that is supposed to be associated with this state and probability. NOTE: this
-             * is ignored by this particular function but not by the overloaded functions.
-             */
-            template<typename ValueType>
-            void addProbabilityToChoice(Choice<ValueType>& choice, uint_fast64_t state, ValueType probability, boost::container::flat_set<uint_fast64_t> const& labels) {
-                choice.getOrAddEntry(state) += probability;
-            }
-            
-            /*!
-             * Adds the target state and probability to the given choice and labels it accordingly. This function overloads
-             * with other functions to ensure the proper treatment of labels.
-             *
-             * @param choice The choice to which to add the target state and probability.
-             * @param state The target state of the probability.
-             * @param probability The probability to reach the target state in one step.
-             * @param labels A set of labels that is supposed to be associated with this state and probability.
-             */
-            template<typename ValueType>
-            void addProbabilityToChoice(Choice<storm::storage::LabeledValues<ValueType>>& choice, uint_fast64_t state, ValueType probability, boost::container::flat_set<uint_fast64_t> const& labels) {
-                auto& labeledEntry = choice.getOrAddEntry(state);
-                labeledEntry.addValue(probability, labels);
-            }
-            
-            // A structure storing information about the used variables of the program.
-            struct VariableInformation {
-                VariableInformation() : booleanVariables(), booleanVariableToIndexMap(), integerVariables(), integerVariableToIndexMap() {
-                    // Intentinally left empty.
-                }
-                
-                // List of all boolean variables.
-                std::vector<storm::ir::BooleanVariable> booleanVariables;
-                
-                // A mapping of boolean variable names to their indices.
-                std::map<std::string, uint_fast64_t> booleanVariableToIndexMap;
-                                
-                // List of all integer variables.
-                std::vector<storm::ir::IntegerVariable> integerVariables;
-                
-                // List of all lower bounds for integer variables.
-                std::vector<int_fast64_t> lowerBounds;
-                
-                // List of all upper bounds for integer variables.
-                std::vector<int_fast64_t> upperBounds;
-                
-                // A mapping of integer variable names to their indices.
-                std::map<std::string, uint_fast64_t> integerVariableToIndexMap;
-            };
-
-            /*!
-             * Aggregates information about the variables in the program.
-             *
-             * @param program The program whose variables to aggregate.
-             * @return A structure containing information about the variables in the program.
-             */
-            static VariableInformation createVariableInformation(storm::ir::Program const& program) {
-                VariableInformation result;
-                
-                uint_fast64_t numberOfIntegerVariables = 0;
-                uint_fast64_t numberOfBooleanVariables = 0;
-                
-                // Count number of variables.
-                numberOfBooleanVariables += program.getNumberOfGlobalBooleanVariables();
-                numberOfIntegerVariables += program.getNumberOfGlobalIntegerVariables();
-                for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
-                    numberOfBooleanVariables += program.getModule(i).getNumberOfBooleanVariables();
-                    numberOfIntegerVariables += program.getModule(i).getNumberOfIntegerVariables();
-                }
-                
-                // Resize the variable vectors appropriately.
-                result.booleanVariables.resize(numberOfBooleanVariables);
-                result.integerVariables.resize(numberOfIntegerVariables);
-                result.lowerBounds.resize(numberOfIntegerVariables);
-                result.upperBounds.resize(numberOfIntegerVariables);
-                
-                // Create variables.
-                for (uint_fast64_t i = 0; i < program.getNumberOfGlobalBooleanVariables(); ++i) {
-                    storm::ir::BooleanVariable const& var = program.getGlobalBooleanVariable(i);
-                    result.booleanVariables[var.getGlobalIndex()] = var;
-                    result.booleanVariableToIndexMap[var.getName()] = var.getGlobalIndex();
-                }
-                for (uint_fast64_t i = 0; i < program.getNumberOfGlobalIntegerVariables(); ++i) {
-                    storm::ir::IntegerVariable const& var = program.getGlobalIntegerVariable(i);
-                    result.integerVariables[var.getGlobalIndex()] = var;
-                    result.integerVariableToIndexMap[var.getName()] = var.getGlobalIndex();
-                    result.lowerBounds[var.getGlobalIndex()] = var.getLowerBound()->getValueAsInt(nullptr);
-                    result.upperBounds[var.getGlobalIndex()] = var.getUpperBound()->getValueAsInt(nullptr);
-                }
-                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& var = module.getBooleanVariable(j);
-                        result.booleanVariables[var.getGlobalIndex()] = var;
-                        result.booleanVariableToIndexMap[var.getName()] = var.getGlobalIndex();
-                    }
-                    for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) {
-                        storm::ir::IntegerVariable const& var = module.getIntegerVariable(j);
-                        result.integerVariables[var.getGlobalIndex()] = var;
-                        result.integerVariableToIndexMap[var.getName()] = var.getGlobalIndex();
-                        result.lowerBounds[var.getGlobalIndex()] = var.getLowerBound()->getValueAsInt(nullptr);
-                        result.upperBounds[var.getGlobalIndex()] = var.getUpperBound()->getValueAsInt(nullptr);
-                    }
-                }
-                
-                return result;
-            }
-            
-            /*!
-             * Generates the initial state of the given program.
-             *
-             * @param program The program for which to construct the initial state.
-             * @param variableInformation A structure with information about the variables in the program.
-             * @return The initial state.
-             */
-            static StateType* getInitialState(storm::ir::Program const& program, VariableInformation const& variableInformation) {
-                StateType* initialState = new StateType();
-                initialState->first.resize(variableInformation.booleanVariables.size());
-                initialState->second.resize(variableInformation.integerVariables.size());
-                
-                // Start with boolean variables.
-                for (uint_fast64_t i = 0; i < variableInformation.booleanVariables.size(); ++i) {
-                    // Check if an initial value is given
-                    if (variableInformation.booleanVariables[i].getInitialValue().get() == nullptr) {
-                        // If no initial value was given, we assume that the variable is initially false.
-                        std::get<0>(*initialState)[i] = false;
-                    } else {
-                        // Initial value was given.
-                        bool initialValue = variableInformation.booleanVariables[i].getInitialValue()->getValueAsBool(nullptr);
-                        std::get<0>(*initialState)[i] = initialValue;
-                    }
-                }
-                
-                // Now process integer variables.
-                for (uint_fast64_t i = 0; i < variableInformation.integerVariables.size(); ++i) {
-                    // Check if an initial value was given.
-                    if (variableInformation.integerVariables[i].getInitialValue().get() == nullptr) {
-                        // No initial value was given, so we assume that the variable initially has the least value it can take.
-                        std::get<1>(*initialState)[i] = variableInformation.integerVariables[i].getLowerBound()->getValueAsInt(nullptr);
-                    } else {
-                        // Initial value was given.
-                        int_fast64_t initialValue = variableInformation.integerVariables[i].getInitialValue()->getValueAsInt(nullptr);
-                        std::get<1>(*initialState)[i] = initialValue;
-                    }
-                }
-                
-                LOG4CPLUS_DEBUG(logger, "Generated initial state.");
-                return initialState;
-            }
-            
-            /*!
-             * Sets some boolean variable in the given state object.
-             *
-             * @param state The state to modify.
-             * @param index The index of the boolean variable to modify.
-             * @param value The new value of the variable.
-             */
-            static void setValue(StateType* state, uint_fast64_t index, bool value) {
-                std::get<0>(*state)[index] = value;
-            }
-            
-            /*!
-             * Set some integer variable in the given state object.
-             *
-             * @param state The state to modify.
-             * @param index index of the integer variable to modify.
-             * @param value The new value of the variable.
-             */
-            static void setValue(StateType* state, uint_fast64_t index, int_fast64_t value) {
-                std::get<1>(*state)[index] = value;
-            }
-
-            /*!
-             * Defines the undefined constants of the given program using the given string.
-             *
-             * @param program The program in which to define the constants.
-             * @param constantDefinitionString A comma-separated list of constant definitions.
-             */
-            static void defineUndefinedConstants(storm::ir::Program& program, std::string const& constantDefinitionString) {
-                if (!constantDefinitionString.empty()) {
-                    // Parse the string that defines the undefined constants of the model and make sure that it contains exactly
-                    // one value for each undefined constant of the model.
-                    std::vector<std::string> definitions;
-                    boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
-                    for (auto& definition : definitions) {
-                        boost::trim(definition);
-                        
-                        // Check whether the token could be a legal constant definition.
-                        uint_fast64_t positionOfAssignmentOperator = definition.find('=');
-                        if (positionOfAssignmentOperator == std::string::npos) {
-                            throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: syntax error.";
-                        }
-                        
-                        // Now extract the variable name and the value from the string.
-                        std::string constantName = definition.substr(0, positionOfAssignmentOperator);
-                        boost::trim(constantName);
-                        std::string value = definition.substr(positionOfAssignmentOperator + 1);
-                        boost::trim(value);
-                        
-                        // Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
-                        if (program.hasUndefinedBooleanConstant(constantName)) {
-                            if (value == "true") {
-                                program.getUndefinedBooleanConstantExpression(constantName)->define(true);
-                            } else if (value == "false") {
-                                program.getUndefinedBooleanConstantExpression(constantName)->define(false);
-                            } else {
-                                throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
-                            }
-                        } else if (program.hasUndefinedIntegerConstant(constantName)) {
-                            try {
-                                int_fast64_t integerValue = std::stoi(value);
-                                program.getUndefinedIntegerConstantExpression(constantName)->define(integerValue);
-                            } catch (std::invalid_argument const&) {
-                                throw storm::exceptions::InvalidArgumentException() << "Illegal value of integer constant: " << value << ".";
-                            } catch (std::out_of_range const&) {
-                                throw storm::exceptions::InvalidArgumentException() << "Illegal value of integer constant: " << value << " (value too big).";
-                            }
-                        } else if (program.hasUndefinedDoubleConstant(constantName)) {
-                            try {
-                                double doubleValue = std::stod(value);
-                                program.getUndefinedDoubleConstantExpression(constantName)->define(doubleValue);
-                            } catch (std::invalid_argument const&) {
-                                throw storm::exceptions::InvalidArgumentException() << "Illegal value of double constant: " << value << ".";
-                            } catch (std::out_of_range const&) {
-                                throw storm::exceptions::InvalidArgumentException() << "Illegal value of double constant: " << value << " (value too big).";
-                            }
-                            
-                        } else {
-                            throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: unknown undefined constant " << constantName << ".";
-                        }
-                    }
-                }
-            }
-            
-            /*!
-             * Undefines all previously defined constants in the given program.
-             *
-             * @param program The program in which to undefine the constants.
-             */
-            static void undefineUndefinedConstants(storm::ir::Program& program) {
-                for (auto const& nameExpressionPair : program.getBooleanUndefinedConstantExpressionsMap()) {
-                    nameExpressionPair.second->undefine();
-                }
-                for (auto const& nameExpressionPair : program.getIntegerUndefinedConstantExpressionsMap()) {
-                    nameExpressionPair.second->undefine();
-                }
-                for (auto const& nameExpressionPair : program.getDoubleUndefinedConstantExpressionsMap()) {
-                    nameExpressionPair.second->undefine();
-                }
-            }
-
-            /*!
-             * Computes the weakest precondition of the given boolean expression wrt. the given updates. The weakest
-             * precondition is the most liberal expression that must hold in order to satisfy the given boolean
-             * expression after performing the updates. The updates must be disjoint in the sense that they must not
-             * assign an expression to a variable twice or more.
-             *
-             * @param expression The expression for which to build the weakest precondition.
-             * @param update The update with respect to which to compute the weakest precondition.
-             */
-            std::unique_ptr<storm::ir::expressions::BaseExpression> getWeakestPrecondition(std::unique_ptr<storm::ir::expressions::BaseExpression> const& booleanExpression, std::vector<std::reference_wrapper<storm::ir::Update const>> const& updates) {
-                std::map<std::string, std::reference_wrapper<storm::ir::expressions::BaseExpression>> variableToExpressionMap;
-                
-                // Construct the full substitution we need to perform later.
-                for (auto const& update : updates) {
-                    for (auto const& variableAssignmentPair : update.get().getBooleanAssignments()) {
-                        variableToExpressionMap.emplace(variableAssignmentPair.first, *variableAssignmentPair.second.getExpression());
-                    }
-                    for (auto const& variableAssignmentPair : update.get().getIntegerAssignments()) {
-                        variableToExpressionMap.emplace(variableAssignmentPair.first, *variableAssignmentPair.second.getExpression());
-                    }
-                }
-                
-                // Copy the given expression and apply the substitution.
-                return storm::ir::expressions::BaseExpression::substitute(booleanExpression->clone(), variableToExpressionMap);
-            }
-            
-        } // namespace ir
-    } // namespace utility
-} // namespace storm
-
-#endif /* STORM_UTILITY_IRUTILITY_H_ */
diff --git a/src/utility/PrismUtility.h b/src/utility/PrismUtility.h
new file mode 100644
index 000000000..9ed15411a
--- /dev/null
+++ b/src/utility/PrismUtility.h
@@ -0,0 +1,195 @@
+#ifndef STORM_UTILITY_PRISMUTILITY
+#define STORM_UTILITY_PRISMUTILITY
+
+#include "src/storage/LabeledValues.h"
+#include "src/storage/prism/Program.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidArgumentException.h"
+
+namespace storm {
+    namespace utility {
+        namespace prism {
+            // A structure holding information about a particular choice.
+            template<typename ValueType, typename KeyType=uint_fast64_t, typename Compare=std::less<uint_fast64_t>>
+            struct Choice {
+            public:
+                Choice(std::string const& actionLabel) : distribution(), actionLabel(actionLabel), choiceLabels() {
+                    // Intentionally left empty.
+                }
+                
+                /*!
+                 * Returns an iterator to the first element of this choice.
+                 *
+                 * @return An iterator to the first element of this choice.
+                 */
+                typename std::map<KeyType, ValueType>::iterator begin() {
+                    return distribution.begin();
+                }
+                
+                /*!
+                 * Returns an iterator to the first element of this choice.
+                 *
+                 * @return An iterator to the first element of this choice.
+                 */
+                typename std::map<KeyType, ValueType>::const_iterator begin() const {
+                    return distribution.cbegin();
+                }
+                
+                /*!
+                 * Returns an iterator that points past the elements of this choice.
+                 *
+                 * @return An iterator that points past the elements of this choice.
+                 */
+                typename std::map<KeyType, ValueType>::iterator end() {
+                    return distribution.end();
+                }
+                
+                /*!
+                 * Returns an iterator that points past the elements of this choice.
+                 *
+                 * @return An iterator that points past the elements of this choice.
+                 */
+                typename std::map<KeyType, ValueType>::const_iterator end() const {
+                    return distribution.cend();
+                }
+                
+                /*!
+                 * Returns an iterator to the element with the given key, if there is one. Otherwise, the iterator points to
+                 * distribution.end().
+                 *
+                 * @param value The value to find.
+                 * @return An iterator to the element with the given key, if there is one.
+                 */
+                typename std::map<KeyType, ValueType>::iterator find(uint_fast64_t value) {
+                    return distribution.find(value);
+                }
+                
+                /*!
+                 * Inserts the contents of this object to the given output stream.
+                 *
+                 * @param out The stream in which to insert the contents.
+                 */
+                friend std::ostream& operator<<(std::ostream& out, Choice<ValueType> const& choice) {
+                    out << "<";
+                    for (auto const& stateProbabilityPair : choice.distribution) {
+                        out << stateProbabilityPair.first << " : " << stateProbabilityPair.second << ", ";
+                    }
+                    out << ">";
+                    return out;
+                }
+                
+                /*!
+                 * Adds the given label to the labels associated with this choice.
+                 *
+                 * @param label The label to associate with this choice.
+                 */
+                void addChoiceLabel(uint_fast64_t label) {
+                    choiceLabels.insert(label);
+                }
+                
+                /*!
+                 * Adds the given label set to the labels associated with this choice.
+                 *
+                 * @param labelSet The label set to associate with this choice.
+                 */
+                void addChoiceLabels(boost::container::flat_set<uint_fast64_t> const& labelSet) {
+                    for (uint_fast64_t label : labelSet) {
+                        addChoiceLabel(label);
+                    }
+                }
+                
+                /*!
+                 * Retrieves the set of labels associated with this choice.
+                 *
+                 * @return The set of labels associated with this choice.
+                 */
+                boost::container::flat_set<uint_fast64_t> const& getChoiceLabels() const {
+                    return choiceLabels;
+                }
+                
+                /*!
+                 * Retrieves the action label of this choice.
+                 *
+                 * @return The action label of this choice.
+                 */
+                std::string const& getActionLabel() const {
+                    return actionLabel;
+                }
+                
+                /*!
+                 * Retrieves the entry in the choice that is associated with the given state and creates one if none exists,
+                 * yet.
+                 *
+                 * @param state The state for which to add the entry.
+                 * @return A reference to the entry that is associated with the given state.
+                 */
+                ValueType& getOrAddEntry(uint_fast64_t state) {
+                    auto stateProbabilityPair = distribution.find(state);
+                    
+                    if (stateProbabilityPair == distribution.end()) {
+                        distribution[state] = ValueType();
+                    }
+                    return distribution.at(state);
+                }
+                
+                /*!
+                 * Retrieves the entry in the choice that is associated with the given state and creates one if none exists,
+                 * yet.
+                 *
+                 * @param state The state for which to add the entry.
+                 * @return A reference to the entry that is associated with the given state.
+                 */
+                ValueType const& getOrAddEntry(uint_fast64_t state) const {
+                    auto stateProbabilityPair = distribution.find(state);
+                    
+                    if (stateProbabilityPair == distribution.end()) {
+                        distribution[state] = ValueType();
+                    }
+                    return distribution.at(state);
+                }
+                
+            private:
+                // The distribution that is associated with the choice.
+                std::map<KeyType, ValueType, Compare> distribution;
+                
+                // The label of the choice.
+                std::string actionLabel;
+                
+                // The labels that are associated with this choice.
+                boost::container::flat_set<uint_fast64_t> choiceLabels;
+            };
+            
+            /*!
+             * Adds the target state and probability to the given choice and ignores the labels. This function overloads with
+             * other functions to ensure the proper treatment of labels.
+             *
+             * @param choice The choice to which to add the target state and probability.
+             * @param state The target state of the probability.
+             * @param probability The probability to reach the target state in one step.
+             * @param labels A set of labels that is supposed to be associated with this state and probability. NOTE: this
+             * is ignored by this particular function but not by the overloaded functions.
+             */
+            template<typename ValueType>
+            void addProbabilityToChoice(Choice<ValueType>& choice, uint_fast64_t state, ValueType probability, boost::container::flat_set<uint_fast64_t> const& labels) {
+                choice.getOrAddEntry(state) += probability;
+            }
+            
+            /*!
+             * Adds the target state and probability to the given choice and labels it accordingly. This function overloads
+             * with other functions to ensure the proper treatment of labels.
+             *
+             * @param choice The choice to which to add the target state and probability.
+             * @param state The target state of the probability.
+             * @param probability The probability to reach the target state in one step.
+             * @param labels A set of labels that is supposed to be associated with this state and probability.
+             */
+            template<typename ValueType>
+            void addProbabilityToChoice(Choice<storm::storage::LabeledValues<ValueType>>& choice, uint_fast64_t state, ValueType probability, boost::container::flat_set<uint_fast64_t> const& labels) {
+                auto& labeledEntry = choice.getOrAddEntry(state);
+                labeledEntry.addValue(probability, labels);
+            }
+        } // namespace prism
+    } // namespace utility
+} // namespace storm
+
+#endif /* STORM_UTILITY_PRISMUTILITY_H_ */

From 164c8225fd27ebe0d94f96a47a2fd4a6363dfcbe Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 16 Apr 2014 14:41:27 +0200
Subject: [PATCH 074/147] Fixed some minor issues.

Former-commit-id: 80f0ae4c9c91076e0987e19643d2f06f17b51aa8
---
 src/adapters/ExplicitModelAdapter.h           | 27 +++-----
 src/parser/PrismParser.cpp                    |  8 +--
 src/parser/PrismParser.h                      |  2 +-
 .../expressions/BinaryRelationExpression.cpp  |  2 +-
 src/storage/expressions/SimpleValuation.cpp   | 64 ++++++++++++-------
 src/storage/expressions/SimpleValuation.h     | 58 +++++++++--------
 src/storage/prism/Constant.cpp                |  4 ++
 src/storage/prism/Constant.h                  | 10 +++
 src/storage/prism/Program.cpp                 | 12 +++-
 test/functional/storage/ExpressionTest.cpp    | 32 +++++-----
 10 files changed, 127 insertions(+), 92 deletions(-)

diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index 0612f86e1..822ea1d12 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -336,8 +336,11 @@ namespace storm {
                         
                         // Only consider unlabeled commands.
                         if (command.getActionName() != "") continue;
+
                         // Skip the command, if it is not enabled.
-                        if (!command.getGuardExpression().evaluateAsBool(currentState)) continue;
+                        if (!command.getGuardExpression().evaluateAsBool(currentState)) {
+                            continue;
+                        }
                         
                         result.push_back(Choice<ValueType>(""));
                         Choice<ValueType>& choice = result.back();
@@ -521,31 +524,19 @@ namespace storm {
                 
                 // Initialize a queue and insert the initial state.
                 std::queue<uint_fast64_t> stateQueue;
-                uint_fast64_t numberOfBooleanVariables = program.getNumberOfGlobalBooleanVariables();
-                uint_fast64_t numberOfIntegerVariables = program.getNumberOfGlobalIntegerVariables();
-                for (auto const& module : program.getModules()) {
-                    numberOfBooleanVariables += module.getNumberOfBooleanVariables();
-                    numberOfIntegerVariables += module.getNumberOfIntegerVariables();
-                }
-                StateType* initialState = new StateType(numberOfBooleanVariables, numberOfIntegerVariables, 0);
-                uint_fast64_t booleanIndex = 0;
-                uint_fast64_t integerIndex = 0;
+                StateType* initialState = new StateType;
                 for (auto const& booleanVariable : program.getGlobalBooleanVariables()) {
-                    initialState->setIdentifierIndex(booleanVariable.getName(), booleanIndex++);
-                    initialState->setBooleanValue(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
+                    initialState->addBooleanIdentifier(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
                 }
                 for (auto const& integerVariable : program.getGlobalIntegerVariables()) {
-                    initialState->setIdentifierIndex(integerVariable.getName(), booleanIndex++);
-                    initialState->setIntegerValue(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
+                    initialState->addIntegerIdentifier(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
                 }
                 for (auto const& module : program.getModules()) {
                     for (auto const& booleanVariable : module.getBooleanVariables()) {
-                        initialState->setIdentifierIndex(booleanVariable.getName(), booleanIndex++);
-                        initialState->setBooleanValue(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
+                        initialState->addBooleanIdentifier(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
                     }
                     for (auto const& integerVariable : module.getIntegerVariables()) {
-                        initialState->setIdentifierIndex(integerVariable.getName(), integerIndex++);
-                        initialState->setIntegerValue(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
+                        initialState->addIntegerIdentifier(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
                     }
                 }
         
diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index c1a068d5c..6039c2c11 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -157,11 +157,11 @@ namespace storm {
             transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
             transitionRewardDefinition.name("transition reward definition");
             
-            rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"")
-                                     > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)]
-                                         |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
+            rewardModelDefinition = (qi::lit("rewards") > -(qi::lit("\"") > identifier[qi::_a = qi::_1] > qi::lit("\""))
+                                     > +(   stateRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
+                                         |   transitionRewardDefinition[phoenix::push_back(qi::_c, qi::_1)]
                                          )
-                                     >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismParser::createRewardModel, phoenix::ref(*this), qi::_1, qi::_a, qi::_b)];
+                                     >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismParser::createRewardModel, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
             rewardModelDefinition.name("reward model definition");
             
             initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)];
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index e271b2298..3f8f17b65 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -225,7 +225,7 @@ namespace storm {
             qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
             
             // Rules for reward definitions.
-            qi::rule<Iterator, storm::prism::RewardModel(), qi::locals<std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
+            qi::rule<Iterator, storm::prism::RewardModel(), qi::locals<std::string, std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
             qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
             qi::rule<Iterator, storm::prism::TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
             
diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp
index 1b00485b6..7e48c2286 100644
--- a/src/storage/expressions/BinaryRelationExpression.cpp
+++ b/src/storage/expressions/BinaryRelationExpression.cpp
@@ -46,7 +46,7 @@ namespace storm {
         void BinaryRelationExpression::printToStream(std::ostream& stream) const {
             stream << "(" << *this->getFirstOperand();
             switch (this->getRelationType()) {
-                case RelationType::Equal: stream << " == "; break;
+                case RelationType::Equal: stream << " = "; break;
                 case RelationType::NotEqual: stream << " != "; break;
                 case RelationType::Greater: stream << " > "; break;
                 case RelationType::GreaterOrEqual: stream << " >= "; break;
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index 7a456cb09..fb6f0088c 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -4,63 +4,79 @@
 
 namespace storm {
     namespace expressions {
-        SimpleValuation::SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount) : identifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>), booleanValues(booleanVariableCount), integerValues(integerVariableCount), doubleValues(doubleVariableCount) {
+        SimpleValuation::SimpleValuation() : booleanIdentifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>()), integerIdentifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>()), doubleIdentifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>()), booleanValues(), integerValues(), doubleValues() {
             // Intentionally left empty.
         }
         
-        SimpleValuation::SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues) : identifierToIndexMap(identifierToIndexMap), booleanValues(booleanValues), integerValues(integerValues), doubleValues(doubleValues) {
-            // Intentionally left empty.
+        bool SimpleValuation::operator==(SimpleValuation const& other) const {
+            return this->booleanIdentifierToIndexMap.get() == other.booleanIdentifierToIndexMap.get() && this->integerIdentifierToIndexMap.get() == other.integerIdentifierToIndexMap.get() && this->doubleIdentifierToIndexMap.get() == other.doubleIdentifierToIndexMap.get() && this->booleanValues == other.booleanValues && this->integerValues == other.integerValues && this->doubleValues == other.doubleValues;
         }
         
-        bool SimpleValuation::operator==(SimpleValuation const& other) const {
-            return this->identifierToIndexMap.get() == other.identifierToIndexMap.get() && this->booleanValues == other.booleanValues && this->integerValues == other.integerValues && this->doubleValues == other.doubleValues;
+        void SimpleValuation::addBooleanIdentifier(std::string const& name, bool initialValue) {
+            this->booleanIdentifierToIndexMap->emplace(name, this->booleanValues.size());
+            this->booleanValues.push_back(false);
         }
-
-        void SimpleValuation::setIdentifierIndex(std::string const& name, uint_fast64_t index) {
-            (*this->identifierToIndexMap)[name] = index;
+        
+        void SimpleValuation::addIntegerIdentifier(std::string const& name, int_fast64_t initialValue) {
+            this->integerIdentifierToIndexMap->emplace(name, this->integerValues.size());
+            this->integerValues.push_back(initialValue);
+        }
+        
+        void SimpleValuation::addDoubleIdentifier(std::string const& name, double initialValue) {
+            this->doubleIdentifierToIndexMap->emplace(name, this->doubleValues.size());
+            this->doubleValues.push_back(initialValue);
         }
         
         void SimpleValuation::setBooleanValue(std::string const& name, bool value) {
-            this->booleanValues[this->identifierToIndexMap->at(name)] = value;
+            this->booleanValues[this->booleanIdentifierToIndexMap->at(name)] = value;
         }
         
         void SimpleValuation::setIntegerValue(std::string const& name, int_fast64_t value) {
-            this->integerValues[this->identifierToIndexMap->at(name)] = value;
+            this->integerValues[this->integerIdentifierToIndexMap->at(name)] = value;
         }
         
         void SimpleValuation::setDoubleValue(std::string const& name, double value) {
-            this->doubleValues[this->identifierToIndexMap->at(name)] = value;
+            this->doubleValues[this->doubleIdentifierToIndexMap->at(name)] = value;
         }
         
         bool SimpleValuation::getBooleanValue(std::string const& name) const {
-            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            auto const& nameIndexPair = this->booleanIdentifierToIndexMap->find(name);
             return this->booleanValues[nameIndexPair->second];
         }
         
         int_fast64_t SimpleValuation::getIntegerValue(std::string const& name) const {
-            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            auto const& nameIndexPair = this->integerIdentifierToIndexMap->find(name);
             return this->integerValues[nameIndexPair->second];
         }
         
         double SimpleValuation::getDoubleValue(std::string const& name) const {
-            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            auto const& nameIndexPair = this->doubleIdentifierToIndexMap->find(name);
             return this->doubleValues[nameIndexPair->second];
         }
         
         std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation) {
-            stream << "valuation { bool[";
-            for (uint_fast64_t i = 0; i < valuation.booleanValues.size() - 1; ++i) {
-                stream << valuation.booleanValues[i] << ", ";
+            stream << "valuation { bool [";
+            if (!valuation.booleanValues.empty()) {
+                for (uint_fast64_t i = 0; i < valuation.booleanValues.size() - 1; ++i) {
+                    stream << valuation.booleanValues[i] << ", ";
+                }
+                stream << valuation.booleanValues.back();
             }
-            stream << valuation.booleanValues.back() << "] ints[";
-            for (uint_fast64_t i = 0; i < valuation.integerValues.size() - 1; ++i) {
-                stream << valuation.integerValues[i] << ", ";
+            stream << "] int [";
+            if (!valuation.integerValues.empty()) {
+                for (uint_fast64_t i = 0; i < valuation.integerValues.size() - 1; ++i) {
+                    stream << valuation.integerValues[i] << ", ";
+                }
+                stream << valuation.integerValues.back();
             }
-            stream << valuation.integerValues.back() << "] double[";
-            for (uint_fast64_t i = 0; i < valuation.doubleValues.size() - 1; ++i) {
-                stream << valuation.doubleValues[i] << ", ";
+            stream << "] double [";
+            if (!valuation.doubleValues.empty()) {
+                for (uint_fast64_t i = 0; i < valuation.doubleValues.size() - 1; ++i) {
+                    stream << valuation.doubleValues[i] << ", ";
+                }
+                stream << valuation.doubleValues.back();
             }
-            stream << valuation.doubleValues.back() << "] }";
+            stream << "] }";
             
             return stream;
         }
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 16719be00..35b74291b 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -16,30 +16,14 @@ namespace storm {
             friend class SimpleValuationPointerLess;
             
             /*!
-             * Creates a simple valuation that can hold the given number of boolean, integer and double variables.
-             *
-             * @param booleanVariableCount The number of boolean variables in the valuation.
-             * @param integerVariableCount The number of integer variables in the valuation.
-             * @param doubleVariableCount The number of double variables in the valuation.
-             */
-            SimpleValuation(std::size_t booleanVariableCount, std::size_t integerVariableCount, std::size_t doubleVariableCount);
-            
-            /*!
-             * Creates a simple evaluation based on the given identifier to index map and value containers for the
-             * different types of variables.
-             *
-             * @param identifierToIndexMap A shared pointer to a mapping from identifier to their local indices in the
-             * value containers.
-             * @param booleanValues The value container for all boolean identifiers.
-             * @param integerValues The value container for all integer identifiers.
-             * @param doubleValues The value container for all double identifiers.
-             */
-            SimpleValuation(std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap, std::vector<bool> booleanValues, std::vector<int_fast64_t> integerValues, std::vector<double> doubleValues);
+             * Creates a simple valuation without any identifiers.
+            */
+            SimpleValuation();
 
             // Instantiate some constructors and assignments with their default implementations.
             SimpleValuation(SimpleValuation const&) = default;
-            SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
+            SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation&&) = default;
             virtual ~SimpleValuation() = default;
 
@@ -49,12 +33,28 @@ namespace storm {
             bool operator==(SimpleValuation const& other) const;
             
             /*!
-             * Sets the index of the identifier with the given name to the given value.
+             * Adds a boolean identifier with the given name.
+             *
+             * @param name The name of the boolean identifier to add.
+             * @param initialValue The initial value of the identifier.
+             */
+            void addBooleanIdentifier(std::string const& name, bool initialValue = false);
+            
+            /*!
+             * Adds a integer identifier with the given name.
              *
-             * @param name The name of the identifier for which to set the index.
-             * @param index The new index of the identifier.
+             * @param name The name of the integer identifier to add.
+             * @param initialValue The initial value of the identifier.
              */
-            void setIdentifierIndex(std::string const& name, uint_fast64_t index);
+            void addIntegerIdentifier(std::string const& name, int_fast64_t initialValue = 0);
+
+            /*!
+             * Adds a double identifier with the given name.
+             *
+             * @param name The name of the double identifier to add.
+             * @param initialValue The initial value of the identifier.
+             */
+            void addDoubleIdentifier(std::string const& name, double initialValue = 0);
             
             /*!
              * Sets the value of the boolean identifier with the given name to the given value.
@@ -88,8 +88,14 @@ namespace storm {
             friend std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation);
 
         private:
-            // A mapping of identifiers to their local indices in the value containers.
-            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> identifierToIndexMap;
+            // A mapping of boolean identifiers to their local indices in the value container.
+            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> booleanIdentifierToIndexMap;
+            
+            // A mapping of integer identifiers to their local indices in the value container.
+            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> integerIdentifierToIndexMap;
+            
+            // A mapping of double identifiers to their local indices in the value container.
+            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> doubleIdentifierToIndexMap;
             
             // The value container for all boolean identifiers.
             std::vector<bool> booleanValues;
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 83e5f9b2a..55d08d78a 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -26,6 +26,10 @@ namespace storm {
             return this->expression;
         }
         
+        Constant Constant::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return Constant(this->getConstantType(), this->getConstantName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Constant const& constant) {
             stream << "const ";
             switch (constant.getConstantType()) {
diff --git a/src/storage/prism/Constant.h b/src/storage/prism/Constant.h
index b67e1639f..06d8cbf50 100644
--- a/src/storage/prism/Constant.h
+++ b/src/storage/prism/Constant.h
@@ -1,6 +1,8 @@
 #ifndef STORM_STORAGE_PRISM_CONSTANT_H_
 #define STORM_STORAGE_PRISM_CONSTANT_H_
 
+#include <map>
+
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
 
@@ -65,6 +67,14 @@ namespace storm {
              */
             storm::expressions::Expression const& getExpression() const;
             
+            /*!
+             * Substitutes all identifiers in the constant according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting constant.
+             */
+            Constant substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Constant const& constant);
             
         private:
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 49ebd7724..85bfc1958 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -261,10 +261,18 @@ namespace storm {
         Program Program::substituteConstants() const {
             // We start by creating the appropriate substitution
             std::map<std::string, storm::expressions::Expression> constantSubstitution;
-            for (auto const& constant : this->getConstants()) {
+            std::vector<Constant> newConstants(this->getConstants());
+            for (uint_fast64_t constantIndex = 0; constantIndex < newConstants.size(); ++constantIndex) {
+                auto const& constant = newConstants[constantIndex];
                 LOG_THROW(constant.isDefined(), storm::exceptions::InvalidArgumentException, "Cannot substitute constants in program that contains undefined constants.");
                 
+                // Put the corresponding expression in the substitution.
                 constantSubstitution.emplace(constant.getConstantName(), constant.getExpression());
+                
+                // If there is at least one more constant to come, we substitute the costants we have so far.
+                if (constantIndex + 1 < newConstants.size()) {
+                    newConstants[constantIndex + 1] = newConstants[constantIndex + 1].substitute(constantSubstitution);
+                }
             }
             
             // Now we can substitute the constants in all expressions appearing in the program.
@@ -306,7 +314,7 @@ namespace storm {
                 newLabels.emplace_back(label.substitute(constantSubstitution));
             }
             
-            return Program(this->getModelType(), std::vector<Constant>(), newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
+            return Program(this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
         }
         
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 8bb2e4c04..0c19c5bfb 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -359,25 +359,25 @@ TEST(Expression, SimpleEvaluationTest) {
     
     ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolConstExpression);
     
-    ASSERT_NO_THROW(storm::expressions::SimpleValuation valuation(2, 2, 2));
-    storm::expressions::SimpleValuation valuation(2, 2, 2);
-    ASSERT_NO_THROW(valuation.setIdentifierIndex("x", 0));
-    ASSERT_NO_THROW(valuation.setIdentifierIndex("a", 1));
-    ASSERT_NO_THROW(valuation.setIdentifierIndex("y", 0));
-    ASSERT_NO_THROW(valuation.setIdentifierIndex("b", 1));
-    ASSERT_NO_THROW(valuation.setIdentifierIndex("z", 0));
-    ASSERT_NO_THROW(valuation.setIdentifierIndex("c", 1));
+    ASSERT_NO_THROW(storm::expressions::SimpleValuation valuation);
+    storm::expressions::SimpleValuation valuation;
+    ASSERT_NO_THROW(valuation.addBooleanIdentifier("x"));
+    ASSERT_NO_THROW(valuation.addBooleanIdentifier("a"));
+    ASSERT_NO_THROW(valuation.addIntegerIdentifier("y"));
+    ASSERT_NO_THROW(valuation.addIntegerIdentifier("b"));
+    ASSERT_NO_THROW(valuation.addDoubleIdentifier("z"));
+    ASSERT_NO_THROW(valuation.addDoubleIdentifier("c"));
     
-    ASSERT_THROW(tempExpression.evaluateAsDouble(valuation), storm::exceptions::InvalidTypeException);
-    ASSERT_THROW(tempExpression.evaluateAsInt(valuation), storm::exceptions::InvalidTypeException);
-    EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
+    ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
+    ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
+    EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
     ASSERT_NO_THROW(valuation.setBooleanValue("a", true));
-    EXPECT_TRUE(tempExpression.evaluateAsBool(valuation));
+    EXPECT_TRUE(tempExpression.evaluateAsBool(&valuation));
     ASSERT_NO_THROW(valuation.setIntegerValue("y", 3));
-    EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
+    EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
     
     ASSERT_NO_THROW(tempExpression = ((intVarExpression < threeExpression).ite(trueExpression, falseExpression)));
-    ASSERT_THROW(tempExpression.evaluateAsDouble(valuation), storm::exceptions::InvalidTypeException);
-    ASSERT_THROW(tempExpression.evaluateAsInt(valuation), storm::exceptions::InvalidTypeException);
-    EXPECT_FALSE(tempExpression.evaluateAsBool(valuation));
+    ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
+    ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
+    EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
 }
\ No newline at end of file

From cc625a2e00c0346cf7d751ea12263595654d2550 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 16 Apr 2014 17:32:35 +0200
Subject: [PATCH 075/147] Added a ton of ifndefs, because MSVC does not yet
 support defaulting move constructors/assignments.

Former-commit-id: 105792abace0ecda8a606e499be3f29b97eddc57
---
 src/storage/expressions/BaseExpression.h                    | 5 ++++-
 src/storage/expressions/BinaryBooleanFunctionExpression.h   | 3 +++
 src/storage/expressions/BinaryExpression.h                  | 3 +++
 src/storage/expressions/BinaryNumericalFunctionExpression.h | 3 +++
 src/storage/expressions/BinaryRelationExpression.h          | 3 +++
 src/storage/expressions/BooleanConstantExpression.h         | 3 +++
 src/storage/expressions/BooleanLiteralExpression.h          | 3 +++
 src/storage/expressions/ConstantExpression.h                | 3 +++
 src/storage/expressions/DoubleConstantExpression.h          | 3 +++
 src/storage/expressions/DoubleLiteralExpression.h           | 3 +++
 src/storage/expressions/Expression.h                        | 3 +++
 src/storage/expressions/Expressions.h                       | 1 +
 src/storage/expressions/IfThenElseExpression.h              | 3 +++
 src/storage/expressions/IntegerConstantExpression.h         | 3 +++
 src/storage/expressions/IntegerLiteralExpression.h          | 3 +++
 src/storage/expressions/UnaryBooleanFunctionExpression.h    | 3 +++
 src/storage/expressions/UnaryExpression.h                   | 3 +++
 src/storage/expressions/UnaryNumericalFunctionExpression.h  | 3 +++
 src/storage/expressions/VariableExpression.h                | 5 ++++-
 src/storage/prism/Assignment.h                              | 3 +++
 src/storage/prism/BooleanVariable.h                         | 3 +++
 src/storage/prism/Command.h                                 | 3 +++
 src/storage/prism/Constant.h                                | 3 +++
 src/storage/prism/Formula.h                                 | 3 +++
 src/storage/prism/IntegerVariable.h                         | 3 +++
 src/storage/prism/Label.h                                   | 3 +++
 src/storage/prism/LocatedInformation.h                      | 4 ++++
 src/storage/prism/Module.h                                  | 3 +++
 src/storage/prism/Program.h                                 | 3 +++
 src/storage/prism/RewardModel.h                             | 3 +++
 src/storage/prism/StateReward.h                             | 3 +++
 src/storage/prism/TransitionReward.h                        | 3 +++
 src/storage/prism/Update.h                                  | 3 +++
 src/storage/prism/Variable.h                                | 3 +++
 34 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 41684255d..fb3df4514 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -9,6 +9,7 @@
 #include "src/storage/expressions/Valuation.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 #include "src/exceptions/InvalidArgumentException.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -33,9 +34,11 @@ namespace storm {
             
             // Create default versions of constructors and assignments.
             BaseExpression(BaseExpression const&) = default;
-            BaseExpression(BaseExpression&&) = default;
             BaseExpression& operator=(BaseExpression const&) = default;
+#ifndef WINDOWS
+            BaseExpression(BaseExpression&&) = default;
             BaseExpression& operator=(BaseExpression&&) = default;
+#endif
             
             // Make the destructor virtual (to allow destruction via base class pointer) and default it.
             virtual ~BaseExpression() = default;
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index 32dfc387d..7a05a1ab5 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
 
 #include "src/storage/expressions/BinaryExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -25,8 +26,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& other) = default;
             BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression const& other) = default;
+#ifndef WINDOWS
             BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression&&) = default;
             BinaryBooleanFunctionExpression& operator=(BinaryBooleanFunctionExpression&&) = default;
+#endif
             virtual ~BinaryBooleanFunctionExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h
index fd1b1903a..640297a91 100644
--- a/src/storage/expressions/BinaryExpression.h
+++ b/src/storage/expressions/BinaryExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BINARYEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -22,8 +23,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             BinaryExpression(BinaryExpression const& other) = default;
             BinaryExpression& operator=(BinaryExpression const& other) = default;
+#ifndef WINDOWS
             BinaryExpression(BinaryExpression&&) = default;
             BinaryExpression& operator=(BinaryExpression&&) = default;
+#endif
             virtual ~BinaryExpression() = default;
 
             // Override base class methods.
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
index 174763c84..4e8573a4c 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BINARYNUMERICALFUNCTIONEXPRESSION_H_
 
 #include "src/storage/expressions/BinaryExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -25,8 +26,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& other) = default;
             BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression const& other) = default;
+#ifndef WINDOWS
             BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression&&) = default;
             BinaryNumericalFunctionExpression& operator=(BinaryNumericalFunctionExpression&&) = default;
+#endif
             virtual ~BinaryNumericalFunctionExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h
index 7e3e177c5..b88ef71f9 100644
--- a/src/storage/expressions/BinaryRelationExpression.h
+++ b/src/storage/expressions/BinaryRelationExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
 
 #include "src/storage/expressions/BinaryExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -25,8 +26,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             BinaryRelationExpression(BinaryRelationExpression const& other) = default;
             BinaryRelationExpression& operator=(BinaryRelationExpression const& other) = default;
+#ifndef WINDOWS
             BinaryRelationExpression(BinaryRelationExpression&&) = default;
             BinaryRelationExpression& operator=(BinaryRelationExpression&&) = default;
+#endif
             virtual ~BinaryRelationExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
index fc2e3f8e4..dd204d7a5 100644
--- a/src/storage/expressions/BooleanConstantExpression.h
+++ b/src/storage/expressions/BooleanConstantExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
 
 #include "src/storage/expressions/ConstantExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,8 +18,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             BooleanConstantExpression(BooleanConstantExpression const& other) = default;
             BooleanConstantExpression& operator=(BooleanConstantExpression const& other) = default;
+#ifndef WINDOWS
             BooleanConstantExpression(BooleanConstantExpression&&) = default;
             BooleanConstantExpression& operator=(BooleanConstantExpression&&) = default;
+#endif
             virtual ~BooleanConstantExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/BooleanLiteralExpression.h b/src/storage/expressions/BooleanLiteralExpression.h
index 49794b59a..6c0413236 100644
--- a/src/storage/expressions/BooleanLiteralExpression.h
+++ b/src/storage/expressions/BooleanLiteralExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,8 +18,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             BooleanLiteralExpression(BooleanLiteralExpression const& other) = default;
             BooleanLiteralExpression& operator=(BooleanLiteralExpression const& other) = default;
+#ifndef WINDOWS
             BooleanLiteralExpression(BooleanLiteralExpression&&) = default;
             BooleanLiteralExpression& operator=(BooleanLiteralExpression&&) = default;
+#endif
             virtual ~BooleanLiteralExpression() = default;
 
             // Override base class methods.
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
index 70ccf6b35..50f00c235 100644
--- a/src/storage/expressions/ConstantExpression.h
+++ b/src/storage/expressions/ConstantExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -18,8 +19,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             ConstantExpression(ConstantExpression const& other) = default;
             ConstantExpression& operator=(ConstantExpression const& other) = default;
+#ifndef WINDOWS
             ConstantExpression(ConstantExpression&&) = default;
             ConstantExpression& operator=(ConstantExpression&&) = default;
+#endif
             virtual ~ConstantExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h
index 673ef007b..b271bf6db 100644
--- a/src/storage/expressions/DoubleConstantExpression.h
+++ b/src/storage/expressions/DoubleConstantExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
 
 #include "src/storage/expressions/ConstantExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,8 +18,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             DoubleConstantExpression(DoubleConstantExpression const& other) = default;
             DoubleConstantExpression& operator=(DoubleConstantExpression const& other) = default;
+#ifndef WINDOWS
             DoubleConstantExpression(DoubleConstantExpression&&) = default;
             DoubleConstantExpression& operator=(DoubleConstantExpression&&) = default;
+#endif
             virtual ~DoubleConstantExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index 1ed293923..e4bc28b81 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,8 +18,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             DoubleLiteralExpression(DoubleLiteralExpression const& other) = default;
             DoubleLiteralExpression& operator=(DoubleLiteralExpression const& other) = default;
+#ifndef WINDOWS
             DoubleLiteralExpression(DoubleLiteralExpression&&) = default;
             DoubleLiteralExpression& operator=(DoubleLiteralExpression&&) = default;
+#endif
             virtual ~DoubleLiteralExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 2253c0548..ea7d99572 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -4,6 +4,7 @@
 #include <memory>
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -21,8 +22,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             Expression(Expression const& other) = default;
             Expression& operator=(Expression const& other) = default;
+#ifndef WINDOWS
             Expression(Expression&&) = default;
             Expression& operator=(Expression&&) = default;
+#endif
             
             // Static factory methods to create atomic expression parts.
             static Expression createBooleanLiteral(bool value);
diff --git a/src/storage/expressions/Expressions.h b/src/storage/expressions/Expressions.h
index 09febb4a4..df8bbd8ed 100644
--- a/src/storage/expressions/Expressions.h
+++ b/src/storage/expressions/Expressions.h
@@ -1,3 +1,4 @@
+#include "src/storage/expressions/IfThenElseExpression.h"
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/BinaryRelationExpression.h"
diff --git a/src/storage/expressions/IfThenElseExpression.h b/src/storage/expressions/IfThenElseExpression.h
index 1f8e2db41..979cb08f0 100644
--- a/src/storage/expressions/IfThenElseExpression.h
+++ b/src/storage/expressions/IfThenElseExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_IFTHENELSEEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -19,8 +20,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             IfThenElseExpression(IfThenElseExpression const& other) = default;
             IfThenElseExpression& operator=(IfThenElseExpression const& other) = default;
+#ifndef WINDOWS
             IfThenElseExpression(IfThenElseExpression&&) = default;
             IfThenElseExpression& operator=(IfThenElseExpression&&) = default;
+#endif
             virtual ~IfThenElseExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h
index 6a808b215..fcf151ead 100644
--- a/src/storage/expressions/IntegerConstantExpression.h
+++ b/src/storage/expressions/IntegerConstantExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
 
 #include "src/storage/expressions/ConstantExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,8 +18,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             IntegerConstantExpression(IntegerConstantExpression const& other) = default;
             IntegerConstantExpression& operator=(IntegerConstantExpression const& other) = default;
+#ifndef WINDOWS
             IntegerConstantExpression(IntegerConstantExpression&&) = default;
             IntegerConstantExpression& operator=(IntegerConstantExpression&&) = default;
+#endif
             virtual ~IntegerConstantExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
index 6cbce6e17..acc2ad4cc 100644
--- a/src/storage/expressions/IntegerLiteralExpression.h
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,8 +18,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             IntegerLiteralExpression(IntegerLiteralExpression const& other) = default;
             IntegerLiteralExpression& operator=(IntegerLiteralExpression const& other) = default;
+#ifndef
             IntegerLiteralExpression(IntegerLiteralExpression&&) = default;
             IntegerLiteralExpression& operator=(IntegerLiteralExpression&&) = default;
+#endif
             virtual ~IntegerLiteralExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h
index 954d3659d..1f2800d8e 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
 
 #include "src/storage/expressions/UnaryExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -24,8 +25,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& other) = default;
             UnaryBooleanFunctionExpression& operator=(UnaryBooleanFunctionExpression const& other) = default;
+#ifndef WINDOWS
             UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression&&) = default;
             UnaryBooleanFunctionExpression& operator=(UnaryBooleanFunctionExpression&&) = default;
+#endif
             virtual ~UnaryBooleanFunctionExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
index 686e97c4e..f81bc08ad 100644
--- a/src/storage/expressions/UnaryExpression.h
+++ b/src/storage/expressions/UnaryExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_UNARYEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -18,8 +19,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             UnaryExpression(UnaryExpression const& other);
             UnaryExpression& operator=(UnaryExpression const& other);
+#ifndef WINDOWS
             UnaryExpression(UnaryExpression&&) = default;
             UnaryExpression& operator=(UnaryExpression&&) = default;
+#endif
             virtual ~UnaryExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h
index be717e564..daa0df40f 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_UNARYNUMERICALFUNCTIONEXPRESSION_H_
 
 #include "src/storage/expressions/UnaryExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -24,8 +25,10 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& other) = default;
             UnaryNumericalFunctionExpression& operator=(UnaryNumericalFunctionExpression const& other) = default;
+#ifndef WINDOWS
             UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression&&) = default;
             UnaryNumericalFunctionExpression& operator=(UnaryNumericalFunctionExpression&&) = default;
+#endif
             virtual ~UnaryNumericalFunctionExpression() = default;
             
             // Override base class methods.
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index 1b86274a9..2d83b7160 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_VARIABLEEXPRESSION_H_
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -17,9 +18,11 @@ namespace storm {
             
             // Instantiate constructors and assignments with their default implementations.
             VariableExpression(VariableExpression const&) = default;
-            VariableExpression(VariableExpression&&) = default;
             VariableExpression& operator=(VariableExpression const&) = default;
+#ifndef WINDOWS
+            VariableExpression(VariableExpression&&) = default;
             VariableExpression& operator=(VariableExpression&&) = default;
+#endif
             virtual ~VariableExpression() = default;
 
             // Override base class methods.
diff --git a/src/storage/prism/Assignment.h b/src/storage/prism/Assignment.h
index cf71c8960..c6604a03e 100644
--- a/src/storage/prism/Assignment.h
+++ b/src/storage/prism/Assignment.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -24,8 +25,10 @@ namespace storm {
             Assignment() = default;
             Assignment(Assignment const& other) = default;
             Assignment& operator=(Assignment const& other)= default;
+#ifndef WINDOWS
             Assignment(Assignment&& other) = default;
             Assignment& operator=(Assignment&& other) = default;
+#endif
             
             /*!
              * Retrieves the name of the variable that this assignment targets.
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
index 6c70fbafb..f32035010 100644
--- a/src/storage/prism/BooleanVariable.h
+++ b/src/storage/prism/BooleanVariable.h
@@ -4,6 +4,7 @@
 #include <map>
 
 #include "src/storage/prism/Variable.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -13,8 +14,10 @@ namespace storm {
             BooleanVariable() = default;
             BooleanVariable(BooleanVariable const& other) = default;
             BooleanVariable& operator=(BooleanVariable const& other)= default;
+#ifndef WINDOWS
             BooleanVariable(BooleanVariable&& other) = default;
             BooleanVariable& operator=(BooleanVariable&& other) = default;
+#endif
 
             /*!
              * Creates a boolean variable with the given name and the default initial value expression.
diff --git a/src/storage/prism/Command.h b/src/storage/prism/Command.h
index 91831d421..6e32eba5e 100644
--- a/src/storage/prism/Command.h
+++ b/src/storage/prism/Command.h
@@ -7,6 +7,7 @@
 
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/prism/Update.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -28,8 +29,10 @@ namespace storm {
             Command() = default;
             Command(Command const& other) = default;
             Command& operator=(Command const& other)= default;
+#ifndef WINDOWS
             Command(Command&& other) = default;
             Command& operator=(Command&& other) = default;
+#endif
             
             /*!
              * Retrieves the action name of this command.
diff --git a/src/storage/prism/Constant.h b/src/storage/prism/Constant.h
index 06d8cbf50..0e651b337 100644
--- a/src/storage/prism/Constant.h
+++ b/src/storage/prism/Constant.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -35,8 +36,10 @@ namespace storm {
             Constant() = default;
             Constant(Constant const& other) = default;
             Constant& operator=(Constant const& other)= default;
+#ifndef WINDOWS
             Constant(Constant&& other) = default;
             Constant& operator=(Constant&& other) = default;
+#endif
             
             /*!
              * Retrieves the name of the constant.
diff --git a/src/storage/prism/Formula.h b/src/storage/prism/Formula.h
index d507aebb1..167168577 100644
--- a/src/storage/prism/Formula.h
+++ b/src/storage/prism/Formula.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -25,8 +26,10 @@ namespace storm {
             Formula() = default;
             Formula(Formula const& other) = default;
             Formula& operator=(Formula const& other)= default;
+#ifndef WINDOWS
             Formula(Formula&& other) = default;
             Formula& operator=(Formula&& other) = default;
+#endif
             
             /*!
              * Retrieves the name that is associated with this formula.
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
index f85e58701..75e1c513e 100644
--- a/src/storage/prism/IntegerVariable.h
+++ b/src/storage/prism/IntegerVariable.h
@@ -4,6 +4,7 @@
 #include <map>
 
 #include "src/storage/prism/Variable.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -13,8 +14,10 @@ namespace storm {
             IntegerVariable() = default;
             IntegerVariable(IntegerVariable const& other) = default;
             IntegerVariable& operator=(IntegerVariable const& other)= default;
+#ifndef WINDOWS
             IntegerVariable(IntegerVariable&& other) = default;
             IntegerVariable& operator=(IntegerVariable&& other) = default;
+#endif
 
             /*!
              * Creates an integer variable with the given name and a default initial value.
diff --git a/src/storage/prism/Label.h b/src/storage/prism/Label.h
index 18899b41d..e9889bde1 100644
--- a/src/storage/prism/Label.h
+++ b/src/storage/prism/Label.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -25,8 +26,10 @@ namespace storm {
             Label() = default;
             Label(Label const& other) = default;
             Label& operator=(Label const& other)= default;
+#ifndef WINDOWS
             Label(Label&& other) = default;
             Label& operator=(Label&& other) = default;
+#endif
             
             /*!
              * Retrieves the name that is associated with this label.
diff --git a/src/storage/prism/LocatedInformation.h b/src/storage/prism/LocatedInformation.h
index 09921a871..8aa4d301e 100644
--- a/src/storage/prism/LocatedInformation.h
+++ b/src/storage/prism/LocatedInformation.h
@@ -3,6 +3,8 @@
 
 #include <string>
 
+#include "src/utility/OsDetection.h"
+
 namespace storm {
     namespace prism {
         class LocatedInformation {
@@ -19,8 +21,10 @@ namespace storm {
             LocatedInformation() = default;
             LocatedInformation(LocatedInformation const& other) = default;
             LocatedInformation& operator=(LocatedInformation const& other)= default;
+#ifndef WINDOWS
             LocatedInformation(LocatedInformation&& other) = default;
             LocatedInformation& operator=(LocatedInformation&& other) = default;
+#endif
             
             /*!
              * Retrieves the name of the file in which the information was found.
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index ba23c23c5..f4fd21f29 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -11,6 +11,7 @@
 #include "src/storage/prism/IntegerVariable.h"
 #include "src/storage/prism/Command.h"
 #include "src/storage/expressions/VariableExpression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -32,8 +33,10 @@ namespace storm {
             Module() = default;
             Module(Module const& other) = default;
             Module& operator=(Module const& other)= default;
+#ifndef WINDOWS
             Module(Module&& other) = default;
             Module& operator=(Module&& other) = default;
+#endif
             
             /*!
              * Retrieves the number of boolean variables in the module.
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 6f4c5e3b1..40f8047e1 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -12,6 +12,7 @@
 #include "src/storage/prism/Label.h"
 #include "src/storage/prism/Module.h"
 #include "src/storage/prism/RewardModel.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -48,8 +49,10 @@ namespace storm {
             Program() = default;
             Program(Program const& other) = default;
             Program& operator=(Program const& other) = default;
+#ifndef WINDOWS
             Program(Program&& other) = default;
             Program& operator=(Program&& other) = default;
+#endif
             
             /*!
              * Retrieves the model type of the model.
diff --git a/src/storage/prism/RewardModel.h b/src/storage/prism/RewardModel.h
index be43834e1..3bb68d1b5 100644
--- a/src/storage/prism/RewardModel.h
+++ b/src/storage/prism/RewardModel.h
@@ -7,6 +7,7 @@
 
 #include "src/storage/prism/StateReward.h"
 #include "src/storage/prism/TransitionReward.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -27,8 +28,10 @@ namespace storm {
             RewardModel() = default;
             RewardModel(RewardModel const& other) = default;
             RewardModel& operator=(RewardModel const& other)= default;
+#ifndef WINDOWS
             RewardModel(RewardModel&& other) = default;
             RewardModel& operator=(RewardModel&& other) = default;
+#endif
             
             /*!
              * Retrieves the name of the reward model.
diff --git a/src/storage/prism/StateReward.h b/src/storage/prism/StateReward.h
index ea6050855..f64dc9e4d 100644
--- a/src/storage/prism/StateReward.h
+++ b/src/storage/prism/StateReward.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -25,8 +26,10 @@ namespace storm {
             StateReward() = default;
             StateReward(StateReward const& other) = default;
             StateReward& operator=(StateReward const& other)= default;
+#ifndef WINDOWS
             StateReward(StateReward&& other) = default;
             StateReward& operator=(StateReward&& other) = default;
+#endif
             
             /*!
              * Retrieves the state predicate that is associated with this state reward.
diff --git a/src/storage/prism/TransitionReward.h b/src/storage/prism/TransitionReward.h
index 987d7dc89..2c118cec7 100644
--- a/src/storage/prism/TransitionReward.h
+++ b/src/storage/prism/TransitionReward.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -27,8 +28,10 @@ namespace storm {
             TransitionReward() = default;
             TransitionReward(TransitionReward const& other) = default;
             TransitionReward& operator=(TransitionReward const& other)= default;
+#ifndef WINDOWS
             TransitionReward(TransitionReward&& other) = default;
             TransitionReward& operator=(TransitionReward&& other) = default;
+#endif
             
             /*!
              * Retrieves the action name that is associated with this transition reward.
diff --git a/src/storage/prism/Update.h b/src/storage/prism/Update.h
index 176111acb..b48aa99e4 100644
--- a/src/storage/prism/Update.h
+++ b/src/storage/prism/Update.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/prism/Assignment.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -25,8 +26,10 @@ namespace storm {
             Update() = default;
             Update(Update const& other) = default;
             Update& operator=(Update const& other)= default;
+#ifndef WINDOWS
             Update(Update&& other) = default;
             Update& operator=(Update&& other) = default;
+#endif
             
             /*!
              * Retrieves the expression for the likelihood of this update.
diff --git a/src/storage/prism/Variable.h b/src/storage/prism/Variable.h
index 51516bc24..586887870 100644
--- a/src/storage/prism/Variable.h
+++ b/src/storage/prism/Variable.h
@@ -5,6 +5,7 @@
 
 #include "src/storage/prism/LocatedInformation.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace prism {
@@ -13,8 +14,10 @@ namespace storm {
             // Create default implementations of constructors/assignment.
             Variable(Variable const& otherVariable) = default;
             Variable& operator=(Variable const& otherVariable)= default;
+#ifndef WINDOWS
             Variable(Variable&& otherVariable) = default;
             Variable& operator=(Variable&& otherVariable) = default;
+#endif
             
             /*!
              * Retrieves the name of the variable.

From 88a5be5b975077bc888e1975f73d1265b7251d38 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 16 Apr 2014 17:59:22 +0200
Subject: [PATCH 076/147] Unified some method names.

Former-commit-id: 3cda728bf6351264d0a241dd4c6c019067a39965
---
 src/adapters/ExplicitModelAdapter.h           | 10 +++++-----
 .../expressions/IntegerLiteralExpression.h    |  2 +-
 src/storage/prism/Constant.cpp                | 18 ++++++++---------
 src/storage/prism/Constant.h                  | 14 ++++++-------
 src/storage/prism/Formula.cpp                 | 12 +++++------
 src/storage/prism/Formula.h                   | 13 ++++++------
 src/storage/prism/IntegerVariable.cpp         |  4 ++--
 src/storage/prism/IntegerVariable.h           |  8 ++++----
 src/storage/prism/Label.cpp                   | 10 +++++-----
 src/storage/prism/Label.h                     |  8 ++++----
 src/storage/prism/Program.cpp                 | 20 +++++++++----------
 src/storage/prism/Variable.cpp                |  6 +++---
 src/storage/prism/Variable.h                  |  6 +++---
 13 files changed, 65 insertions(+), 66 deletions(-)

diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index 822ea1d12..777807c06 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -120,7 +120,7 @@ namespace storm {
                             LOG_THROW(definedConstants.find(constantName) == definedConstants.end(), storm::exceptions::InvalidArgumentException, "Illegally trying to define constant '" << constantName <<"' twice.");
                             definedConstants.insert(constantName);
                             
-                            if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Bool) {
+                            if (constant.getType() == storm::expressions::ExpressionReturnType::Bool) {
                                 if (value == "true") {
                                     constantDefinitions[constantName] = storm::expressions::Expression::createTrue();
                                 } else if (value == "false") {
@@ -128,10 +128,10 @@ namespace storm {
                                 } else {
                                     throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
                                 }
-                            } else if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Int) {
+                            } else if (constant.getType() == storm::expressions::ExpressionReturnType::Int) {
                                 int_fast64_t integerValue = std::stoi(value);
                                 constantDefinitions[constantName] = storm::expressions::Expression::createIntegerLiteral(integerValue);
-                            } else if (constant.getConstantType() == storm::expressions::ExpressionReturnType::Double) {
+                            } else if (constant.getType() == storm::expressions::ExpressionReturnType::Double) {
                                 double doubleValue = std::stod(value);
                                 constantDefinitions[constantName] = storm::expressions::Expression::createDoubleLiteral(doubleValue);
                             }
@@ -753,13 +753,13 @@ namespace storm {
                 
                 // Initialize labeling.
                 for (auto const& label : labels) {
-                    result.addAtomicProposition(label.getLabelName());
+                    result.addAtomicProposition(label.getName());
                 }
                 for (uint_fast64_t index = 0; index < stateInformation.reachableStates.size(); index++) {
                     for (auto const& label : labels) {
                         // Add label to state, if the corresponding expression is true.
                         if (label.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates[index])) {
-                            result.addAtomicPropositionToState(label.getLabelName(), index);
+                            result.addAtomicPropositionToState(label.getName(), index);
                         }
                     }
                 }
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
index acc2ad4cc..8d50fe688 100644
--- a/src/storage/expressions/IntegerLiteralExpression.h
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -18,7 +18,7 @@ namespace storm {
             // Instantiate constructors and assignments with their default implementations.
             IntegerLiteralExpression(IntegerLiteralExpression const& other) = default;
             IntegerLiteralExpression& operator=(IntegerLiteralExpression const& other) = default;
-#ifndef
+#ifndef WINDOWS
             IntegerLiteralExpression(IntegerLiteralExpression&&) = default;
             IntegerLiteralExpression& operator=(IntegerLiteralExpression&&) = default;
 #endif
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 55d08d78a..160e9ad22 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -2,20 +2,20 @@
 
 namespace storm {
     namespace prism {
-        Constant::Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(true), expression(expression) {
+        Constant::Constant(storm::expressions::ExpressionReturnType type, std::string const& name, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), type(type), name(name), defined(true), expression(expression) {
             // Intentionally left empty.
         }
         
-        Constant::Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), constantType(constantType), constantName(constantName), defined(false), expression() {
+        Constant::Constant(storm::expressions::ExpressionReturnType type, std::string const& name, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), type(type), name(name), defined(false), expression() {
             // Intentionally left empty.
         }
         
-        std::string const& Constant::getConstantName() const {
-            return this->constantName;
+        std::string const& Constant::getName() const {
+            return this->name;
         }
         
-        storm::expressions::ExpressionReturnType Constant::getConstantType() const {
-            return this->constantType;
+        storm::expressions::ExpressionReturnType Constant::getType() const {
+            return this->type;
         }
         
         bool Constant::isDefined() const {
@@ -27,18 +27,18 @@ namespace storm {
         }
         
         Constant Constant::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Constant(this->getConstantType(), this->getConstantName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Constant(this->getType(), this->getName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Constant const& constant) {
             stream << "const ";
-            switch (constant.getConstantType()) {
+            switch (constant.getType()) {
                 case storm::expressions::ExpressionReturnType::Undefined: stream << "undefined "; break;
                 case storm::expressions::ExpressionReturnType::Bool: stream << "bool "; break;
                 case storm::expressions::ExpressionReturnType::Int: stream << "int "; break;
                 case storm::expressions::ExpressionReturnType::Double: stream << "double "; break;
             }
-            stream << constant.getConstantName();
+            stream << constant.getName();
             if (constant.isDefined()) {
                 stream << " = " << constant.getExpression();
             }
diff --git a/src/storage/prism/Constant.h b/src/storage/prism/Constant.h
index 0e651b337..2e1c27590 100644
--- a/src/storage/prism/Constant.h
+++ b/src/storage/prism/Constant.h
@@ -14,13 +14,13 @@ namespace storm {
             /*!
              * Creates a constant with the given type, name and defining expression.
              *
-             * @param constantType The type of the constant.
-             * @param constantName The name of the constant.
+             * @param type The type of the constant.
+             * @param name The name of the constant.
              * @param expression The expression that defines the constant.
              * @param filename The filename in which the transition reward is defined.
              * @param lineNumber The line number in which the transition reward is defined.
              */
-            Constant(storm::expressions::ExpressionReturnType constantType, std::string const& constantName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Constant(storm::expressions::ExpressionReturnType type, std::string const& name, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
 
             /*!
              * Creates an undefined constant with the given type and name.
@@ -46,14 +46,14 @@ namespace storm {
              *
              * @return The name of the constant.
              */
-            std::string const& getConstantName() const;
+            std::string const& getName() const;
             
             /*!
              * Retrieves the type of the constant.
              *
              * @return The type of the constant;
              */
-            storm::expressions::ExpressionReturnType getConstantType() const;
+            storm::expressions::ExpressionReturnType getType() const;
             
             /*!
              * Retrieves whether the constant is defined, i.e., whether there is an expression defining its value.
@@ -82,10 +82,10 @@ namespace storm {
             
         private:
             // The type of the constant.
-            storm::expressions::ExpressionReturnType constantType;
+            storm::expressions::ExpressionReturnType type;
             
             // The name of the constant.
-            std::string constantName;
+            std::string name;
             
             // A flag that stores whether or not the constant is defined.
             bool defined;
diff --git a/src/storage/prism/Formula.cpp b/src/storage/prism/Formula.cpp
index 875438441..3bf72a7de 100644
--- a/src/storage/prism/Formula.cpp
+++ b/src/storage/prism/Formula.cpp
@@ -2,28 +2,28 @@
 
 namespace storm {
     namespace prism {
-        Formula::Formula(std::string const& formulaName, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), formulaName(formulaName), expression(expression) {
+        Formula::Formula(std::string const& name, storm::expressions::Expression const& expression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), name(name), expression(expression) {
             // Intentionally left empty.
         }
         
-        std::string const& Formula::getFormulaName() const {
-            return this->formulaName;
+        std::string const& Formula::getName() const {
+            return this->name;
         }
         
         storm::expressions::Expression const& Formula::getExpression() const {
             return this->expression;
         }
         
-        storm::expressions::ExpressionReturnType Formula::getReturnType() const {
+        storm::expressions::ExpressionReturnType Formula::getType() const {
             return this->getExpression().getReturnType();
         }
         
         Formula Formula::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Formula(this->getFormulaName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Formula(this->getName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Formula const& formula) {
-            stream << "formula " << formula.getFormulaName() << " = " << formula.getExpression() << ";";
+            stream << "formula " << formula.getName() << " = " << formula.getExpression() << ";";
             return stream;
         }
     }
diff --git a/src/storage/prism/Formula.h b/src/storage/prism/Formula.h
index 167168577..2df8e6d32 100644
--- a/src/storage/prism/Formula.h
+++ b/src/storage/prism/Formula.h
@@ -14,13 +14,12 @@ namespace storm {
             /*!
              * Creates a formula with the given name and expression.
              *
-             * @param formulaName The name of the label.
-             * @param expression The predicate that needs to hold before taking a transition with the previously
-             * specified name in order to obtain the reward.
+             * @param name The name of the formula.
+             * @param expression The expression associated with this formula.
              * @param filename The filename in which the transition reward is defined.
              * @param lineNumber The line number in which the transition reward is defined.
              */
-            Formula(std::string const& formulaName, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Formula(std::string const& name, storm::expressions::Expression const& expression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Formula() = default;
@@ -36,7 +35,7 @@ namespace storm {
              *
              * @return The name that is associated with this formula.
              */
-            std::string const& getFormulaName() const;
+            std::string const& getName() const;
             
             /*!
              * Retrieves the expression that is associated with this formula.
@@ -50,7 +49,7 @@ namespace storm {
              *
              * @return The return type of the formula.
              */
-            storm::expressions::ExpressionReturnType getReturnType() const;
+            storm::expressions::ExpressionReturnType getType() const;
             
             /*!
              * Substitutes all identifiers in the expression of the formula according to the given map.
@@ -64,7 +63,7 @@ namespace storm {
             
         private:
             // The name of the formula.
-            std::string formulaName;
+            std::string name;
             
             // A predicate that needs to be satisfied by states for the label to be attached.
             storm::expressions::Expression expression;
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index 2655dd266..a80b6394e 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -2,11 +2,11 @@
 
 namespace storm {
     namespace prism {
-        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(variableName, lowerBoundExpression, true, filename, lineNumber), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
+        IntegerVariable::IntegerVariable(std::string const& name, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(name, lowerBoundExpression, true, filename, lineNumber), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
             // Intentionally left empty.
         }
 
-        IntegerVariable::IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(variableName, initialValueExpression, false, filename, lineNumber), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
+        IntegerVariable::IntegerVariable(std::string const& name, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(name, initialValueExpression, false, filename, lineNumber), lowerBoundExpression(lowerBoundExpression), upperBoundExpression(upperBoundExpression) {
             // Intentionally left empty.
         }
         
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
index 75e1c513e..a7c069c53 100644
--- a/src/storage/prism/IntegerVariable.h
+++ b/src/storage/prism/IntegerVariable.h
@@ -22,25 +22,25 @@ namespace storm {
             /*!
              * Creates an integer variable with the given name and a default initial value.
              *
-             * @param variableName The name of the variable.
+             * @param name The name of the variable.
              * @param lowerBoundExpression A constant expression defining the lower bound of the domain of the variable.
              * @param upperBoundExpression A constant expression defining the upper bound of the domain of the variable.
              * @param filename The filename in which the variable is defined.
              * @param lineNumber The line number in which the variable is defined.
              */
-            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            IntegerVariable(std::string const& name, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
 
             /*!
              * Creates an integer variable with the given name and the given initial value expression.
              *
-             * @param variableName The name of the variable.
+             * @param name The name of the variable.
              * @param lowerBoundExpression A constant expression defining the lower bound of the domain of the variable.
              * @param upperBoundExpression A constant expression defining the upper bound of the domain of the variable.
              * @param initialValueExpression A constant expression that defines the initial value of the variable.
              * @param filename The filename in which the variable is defined.
              * @param lineNumber The line number in which the variable is defined.
              */
-            IntegerVariable(std::string const& variableName, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            IntegerVariable(std::string const& name, storm::expressions::Expression const& lowerBoundExpression, storm::expressions::Expression const& upperBoundExpression, storm::expressions::Expression const& initialValueExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Retrieves an expression defining the lower bound for this integer variable.
diff --git a/src/storage/prism/Label.cpp b/src/storage/prism/Label.cpp
index 51feae5b4..a78f9079f 100644
--- a/src/storage/prism/Label.cpp
+++ b/src/storage/prism/Label.cpp
@@ -2,12 +2,12 @@
 
 namespace storm {
     namespace prism {
-        Label::Label(std::string const& labelName, storm::expressions::Expression const& statePredicateExpression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), labelName(labelName), statePredicateExpression(statePredicateExpression) {
+        Label::Label(std::string const& name, storm::expressions::Expression const& statePredicateExpression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), name(name), statePredicateExpression(statePredicateExpression) {
             // Intentionally left empty.
         }
 
-        std::string const& Label::getLabelName() const {
-            return this->labelName;
+        std::string const& Label::getName() const {
+            return this->name;
         }
         
         storm::expressions::Expression const& Label::getStatePredicateExpression() const {
@@ -15,11 +15,11 @@ namespace storm {
         }
         
         Label Label::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Label(this->getLabelName(), this->getStatePredicateExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Label(this->getName(), this->getStatePredicateExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Label const& label) {
-            stream << "label \"" << label.getLabelName() << "\" = " << label.getStatePredicateExpression() << ";";
+            stream << "label \"" << label.getName() << "\" = " << label.getStatePredicateExpression() << ";";
             return stream;
         }
     }
diff --git a/src/storage/prism/Label.h b/src/storage/prism/Label.h
index e9889bde1..96934adf2 100644
--- a/src/storage/prism/Label.h
+++ b/src/storage/prism/Label.h
@@ -14,13 +14,13 @@ namespace storm {
             /*!
              * Creates a label with the given name and state predicate expression.
              *
-             * @param labelName The name of the label.
+             * @param name The name of the label.
              * @param statePredicateExpression The predicate that needs to hold before taking a transition with the previously
              * specified name in order to obtain the reward.
              * @param filename The filename in which the transition reward is defined.
              * @param lineNumber The line number in which the transition reward is defined.
              */
-            Label(std::string const& labelName, storm::expressions::Expression const& statePredicateExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Label(std::string const& name, storm::expressions::Expression const& statePredicateExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             // Create default implementations of constructors/assignment.
             Label() = default;
@@ -36,7 +36,7 @@ namespace storm {
              *
              * @return The name that is associated with this label.
              */
-            std::string const& getLabelName() const;
+            std::string const& getName() const;
             
             /*!
              * Retrieves the state predicate expression that is associated with this label.
@@ -57,7 +57,7 @@ namespace storm {
             
         private:
             // The name of the label.
-            std::string labelName;
+            std::string name;
             
             // A predicate that needs to be satisfied by states for the label to be attached.
             storm::expressions::Expression statePredicateExpression;
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 85bfc1958..cdbba3e22 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -169,7 +169,7 @@ namespace storm {
         void Program::createMappings() {
             // Build the mappings for constants, global variables, formulas, modules, reward models and labels.
             for (uint_fast64_t constantIndex = 0; constantIndex < this->getNumberOfConstants(); ++constantIndex) {
-                this->constantToIndexMap[this->getConstants()[constantIndex].getConstantName()] = constantIndex;
+                this->constantToIndexMap[this->getConstants()[constantIndex].getName()] = constantIndex;
             }
             for (uint_fast64_t globalVariableIndex = 0; globalVariableIndex < this->getNumberOfGlobalBooleanVariables(); ++globalVariableIndex) {
                 this->globalBooleanVariableToIndexMap[this->getGlobalBooleanVariables()[globalVariableIndex].getName()] = globalVariableIndex;
@@ -178,7 +178,7 @@ namespace storm {
                 this->globalIntegerVariableToIndexMap[this->getGlobalIntegerVariables()[globalVariableIndex].getName()] = globalVariableIndex;
             }
             for (uint_fast64_t formulaIndex = 0; formulaIndex < this->getNumberOfFormulas(); ++formulaIndex) {
-                this->formulaToIndexMap[this->getFormulas()[formulaIndex].getFormulaName()] = formulaIndex;
+                this->formulaToIndexMap[this->getFormulas()[formulaIndex].getName()] = formulaIndex;
             }
             for (uint_fast64_t moduleIndex = 0; moduleIndex < this->getNumberOfModules(); ++moduleIndex) {
                 this->moduleToIndexMap[this->getModules()[moduleIndex].getName()] = moduleIndex;
@@ -187,7 +187,7 @@ namespace storm {
                 this->rewardModelToIndexMap[this->getRewardModels()[rewardModelIndex].getName()] = rewardModelIndex;
             }
             for (uint_fast64_t labelIndex = 0; labelIndex < this->getNumberOfLabels(); ++labelIndex) {
-                this->labelToIndexMap[this->getLabels()[labelIndex].getLabelName()] = labelIndex;
+                this->labelToIndexMap[this->getLabels()[labelIndex].getName()] = labelIndex;
             }
             
             // Build the mapping from action names to module indices so that the lookup can later be performed quickly.
@@ -226,25 +226,25 @@ namespace storm {
                 // defining expression
                 if (constant.isDefined()) {
                     // Make sure we are not trying to define an already defined constant.
-                    LOG_THROW(constantDefinitions.find(constant.getConstantName()) == constantDefinitions.end(), storm::exceptions::InvalidArgumentException, "Illegally defining already defined constant '" << constant.getConstantName() << "'.");
+                    LOG_THROW(constantDefinitions.find(constant.getName()) == constantDefinitions.end(), storm::exceptions::InvalidArgumentException, "Illegally defining already defined constant '" << constant.getName() << "'.");
                     
                     // Now replace the occurrences of undefined constants in its defining expression.
-                    newConstants.emplace_back(constant.getConstantType(), constant.getConstantName(), constant.getExpression().substitute<std::map>(constantDefinitions), constant.getFilename(), constant.getLineNumber());
+                    newConstants.emplace_back(constant.getType(), constant.getName(), constant.getExpression().substitute<std::map>(constantDefinitions), constant.getFilename(), constant.getLineNumber());
                 } else {
-                    auto const& variableExpressionPair = constantDefinitions.find(constant.getConstantName());
+                    auto const& variableExpressionPair = constantDefinitions.find(constant.getName());
                     
                     // If the constant is not defined by the mapping, we leave it like it is.
                     if (variableExpressionPair == constantDefinitions.end()) {
                         newConstants.emplace_back(constant);
                     } else {
                         // Otherwise, we add it to the defined constants and assign it the appropriate expression.
-                        definedUndefinedConstants.insert(constant.getConstantName());
+                        definedUndefinedConstants.insert(constant.getName());
                         
                         // Make sure the type of the constant is correct.
-                        LOG_THROW(variableExpressionPair->second.getReturnType() == constant.getConstantType(), storm::exceptions::InvalidArgumentException, "Illegal type of expression defining constant '" << constant.getConstantName() << "'.");
+                        LOG_THROW(variableExpressionPair->second.getReturnType() == constant.getType(), storm::exceptions::InvalidArgumentException, "Illegal type of expression defining constant '" << constant.getName() << "'.");
                         
                         // Now create the defined constant.
-                        newConstants.emplace_back(constant.getConstantType(), constant.getConstantName(), variableExpressionPair->second, constant.getFilename(), constant.getLineNumber());
+                        newConstants.emplace_back(constant.getType(), constant.getName(), variableExpressionPair->second, constant.getFilename(), constant.getLineNumber());
                     }
                 }
             }
@@ -267,7 +267,7 @@ namespace storm {
                 LOG_THROW(constant.isDefined(), storm::exceptions::InvalidArgumentException, "Cannot substitute constants in program that contains undefined constants.");
                 
                 // Put the corresponding expression in the substitution.
-                constantSubstitution.emplace(constant.getConstantName(), constant.getExpression());
+                constantSubstitution.emplace(constant.getName(), constant.getExpression());
                 
                 // If there is at least one more constant to come, we substitute the costants we have so far.
                 if (constantIndex + 1 < newConstants.size()) {
diff --git a/src/storage/prism/Variable.cpp b/src/storage/prism/Variable.cpp
index 8ec4f2a98..e6c884813 100644
--- a/src/storage/prism/Variable.cpp
+++ b/src/storage/prism/Variable.cpp
@@ -4,16 +4,16 @@
 
 namespace storm {
     namespace prism {
-        Variable::Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(variableName), initialValueExpression(initialValueExpression), defaultInitialValue(defaultInitialValue) {
+        Variable::Variable(std::string const& name, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), name(name), initialValueExpression(initialValueExpression), defaultInitialValue(defaultInitialValue) {
             // Nothing to do here.
         }
         
-        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variableName(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
+        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), name(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
             // Intentionally left empty.
         }
         
         std::string const& Variable::getName() const {
-            return variableName;
+            return this->name;
         }
         
         bool Variable::hasDefaultInitialValue() const {
diff --git a/src/storage/prism/Variable.h b/src/storage/prism/Variable.h
index 586887870..a4cb76cb9 100644
--- a/src/storage/prism/Variable.h
+++ b/src/storage/prism/Variable.h
@@ -47,14 +47,14 @@ namespace storm {
             /*!
              * Creates a variable with the given name and initial value.
              *
-             * @param variableName The name of the variable.
+             * @param name The name of the variable.
              * @param initialValueExpression The constant expression that defines the initial value of the variable.
              * @param hasDefaultInitialValue A flag indicating whether the initial value of the variable is its default
              * value.
              * @param filename The filename in which the variable is defined.
              * @param lineNumber The line number in which the variable is defined.
              */
-            Variable(std::string const& variableName, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Variable(std::string const& name, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename = "", uint_fast64_t lineNumber = 0);
             
             /*!
              * Creates a copy of the given variable and performs the provided renaming.
@@ -69,7 +69,7 @@ namespace storm {
             
         private:
             // The name of the variable.
-            std::string variableName;
+            std::string name;
             
             // The constant expression defining the initial value of the variable.
             storm::expressions::Expression initialValueExpression;

From dc8921037e9247d1887cf1d855390d8cf656769d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 16 Apr 2014 18:56:04 +0200
Subject: [PATCH 077/147] Added missing test inputs.

Former-commit-id: 537971f3659506aaf496406e00ed78e5aa26bc97
---
 test/functional/parser/prism/coin2.nm         |  60 +++++
 test/functional/parser/prism/crowds5_5.pm     |  69 ++++++
 test/functional/parser/prism/csma2_2.nm       | 130 +++++++++++
 test/functional/parser/prism/die.pm           |  24 ++
 test/functional/parser/prism/firewire.nm      | 170 ++++++++++++++
 test/functional/parser/prism/leader3.nm       |  96 ++++++++
 test/functional/parser/prism/leader3_5.pm     |  85 +++++++
 test/functional/parser/prism/two_dice.nm      |  40 ++++
 test/functional/parser/prism/wlan0_collide.nm | 219 ++++++++++++++++++
 9 files changed, 893 insertions(+)
 create mode 100644 test/functional/parser/prism/coin2.nm
 create mode 100644 test/functional/parser/prism/crowds5_5.pm
 create mode 100644 test/functional/parser/prism/csma2_2.nm
 create mode 100644 test/functional/parser/prism/die.pm
 create mode 100644 test/functional/parser/prism/firewire.nm
 create mode 100644 test/functional/parser/prism/leader3.nm
 create mode 100644 test/functional/parser/prism/leader3_5.pm
 create mode 100644 test/functional/parser/prism/two_dice.nm
 create mode 100644 test/functional/parser/prism/wlan0_collide.nm

diff --git a/test/functional/parser/prism/coin2.nm b/test/functional/parser/prism/coin2.nm
new file mode 100644
index 000000000..a08bb8741
--- /dev/null
+++ b/test/functional/parser/prism/coin2.nm
@@ -0,0 +1,60 @@
+// COIN FLIPPING PROTOCOL FOR POLYNOMIAL RANDOMIZED CONSENSUS [AH90] 
+// gxn/dxp 20/11/00
+
+mdp
+
+// constants
+const int N=2;
+const int K;
+const int range = 2*(K+1)*N;
+const int counter_init = (K+1)*N;
+const int left = N;
+const int right = 2*(K+1)*N - N;
+
+// shared coin
+global counter : [0..range] init counter_init;
+
+module process1
+	
+	// program counter
+	pc1 : [0..3];
+	// 0 - flip
+	// 1 - write 
+	// 2 - check
+	// 3 - finished
+	
+	// local coin
+	coin1 : [0..1];	
+
+	// flip coin
+	[] (pc1=0)  -> 0.5 : (coin1'=0) & (pc1'=1) + 0.5 : (coin1'=1) & (pc1'=1);
+	// write tails -1  (reset coin to add regularity)
+	[] (pc1=1) & (coin1=0) & (counter>0) -> 1 : (counter'=counter-1) & (pc1'=2) & (coin1'=0);
+	// write heads +1 (reset coin to add regularity)
+	[] (pc1=1) & (coin1=1) & (counter<range) -> 1 : (counter'=counter+1) & (pc1'=2) & (coin1'=0);
+	// check
+	// decide tails
+	[] (pc1=2) & (counter<=left) -> 1 : (pc1'=3) & (coin1'=0);
+	// decide heads
+	[] (pc1=2) & (counter>=right) -> 1 : (pc1'=3) & (coin1'=1);
+	// flip again
+	[] (pc1=2) & (counter>left) & (counter<right) -> 1 : (pc1'=0);
+	// loop (all loop together when done)
+	[done] (pc1=3) -> 1 : (pc1'=3);
+
+endmodule
+
+// construct remaining processes through renaming
+module process2 = process1[pc1=pc2,coin1=coin2] endmodule
+
+// labels
+label "finished" = pc1=3 & pc2=3 ;
+label "all_coins_equal_0" = coin1=0 & coin2=0 ;
+label "all_coins_equal_1" = coin1=1 & coin2=1 ;
+label "agree" = coin1=coin2 ;
+
+// rewards
+rewards "steps"
+	true : 1;
+endrewards
+
diff --git a/test/functional/parser/prism/crowds5_5.pm b/test/functional/parser/prism/crowds5_5.pm
new file mode 100644
index 000000000..60bdaa7ea
--- /dev/null
+++ b/test/functional/parser/prism/crowds5_5.pm
@@ -0,0 +1,69 @@
+dtmc
+
+// probability of forwarding
+const double    PF = 0.8;
+const double notPF = .2;  // must be 1-PF
+// probability that a crowd member is bad
+const double  badC = .167;
+ // probability that a crowd member is good
+const double goodC = 0.833;
+// Total number of protocol runs to analyze
+const int TotalRuns = 5;
+// size of the crowd
+const int CrowdSize = 5;
+
+module crowds
+	// protocol phase
+	phase: [0..4] init 0;
+
+	// crowd member good (or bad)
+	good: bool init false;
+
+	// number of protocol runs
+	runCount: [0..TotalRuns] init 0;
+
+	// observe_i is the number of times the attacker observed crowd member i
+	observe0: [0..TotalRuns] init 0;
+
+	observe1: [0..TotalRuns] init 0;
+
+	observe2: [0..TotalRuns] init 0;
+
+	observe3: [0..TotalRuns] init 0;
+
+	observe4: [0..TotalRuns] init 0;
+
+	// the last seen crowd member
+	lastSeen: [0..CrowdSize - 1] init 0;
+
+	// get the protocol started
+	[] phase=0 & runCount<TotalRuns -> 1: (phase'=1) & (runCount'=runCount+1) & (lastSeen'=0);
+
+	// decide whether crowd member is good or bad according to given probabilities
+	[] phase=1 -> goodC : (phase'=2) & (good'=true) + badC : (phase'=2) & (good'=false);
+
+	// if the current member is a good member, update the last seen index (chosen uniformly)
+	[] phase=2 & good -> 1/5 : (lastSeen'=0) & (phase'=3) + 1/5 : (lastSeen'=1) & (phase'=3) + 1/5 : (lastSeen'=2) & (phase'=3) + 1/5 : (lastSeen'=3) & (phase'=3) + 1/5 : (lastSeen'=4) & (phase'=3);
+
+	// if the current member is a bad member, record the most recently seen index
+	[] phase=2 & !good & lastSeen=0 & observe0 < TotalRuns -> 1: (observe0'=observe0+1) & (phase'=4);
+	[] phase=2 & !good & lastSeen=1 & observe1 < TotalRuns -> 1: (observe1'=observe1+1) & (phase'=4);
+	[] phase=2 & !good & lastSeen=2 & observe2 < TotalRuns -> 1: (observe2'=observe2+1) & (phase'=4);
+	[] phase=2 & !good & lastSeen=3 & observe3 < TotalRuns -> 1: (observe3'=observe3+1) & (phase'=4);
+	[] phase=2 & !good & lastSeen=4 & observe4 < TotalRuns -> 1: (observe4'=observe4+1) & (phase'=4);
+
+	// good crowd members forward with probability PF and deliver otherwise
+	[] phase=3 -> PF : (phase'=1) + notPF : (phase'=4);
+
+	// deliver the message and start over
+	[] phase=4 -> 1: (phase'=0);
+
+endmodule
+
+label "observe0Greater1" = observe0>1;
+label "observe1Greater1" = observe1>1;
+label "observe2Greater1" = observe2>1;
+label "observe3Greater1" = observe3>1;
+label "observe4Greater1" = observe4>1;
+label "observeIGreater1" = observe1>1|observe2>1|observe3>1|observe4>1;
+label "observeOnlyTrueSender" = observe0>1&observe1<=1 & observe2<=1 & observe3<=1 & observe4<=1;
diff --git a/test/functional/parser/prism/csma2_2.nm b/test/functional/parser/prism/csma2_2.nm
new file mode 100644
index 000000000..18ec5c897
--- /dev/null
+++ b/test/functional/parser/prism/csma2_2.nm
@@ -0,0 +1,130 @@
+// CSMA/CD protocol - probabilistic version of kronos model (3 stations)
+// gxn/dxp 04/12/01
+
+mdp
+
+// note made changes since cannot have strict inequalities
+// in digital clocks approach and suppose a station only sends one message
+
+// simplified parameters scaled
+const int sigma=1; // time for messages to propagate along the bus
+const int lambda=30; // time to send a message
+
+// actual parameters
+const int N = 2; // number of processes
+const int K = 2; // exponential backoff limit
+const int slot = 2*sigma; // length of slot
+// const int M = floor(pow(2, K))-1 ; // max number of slots to wait
+const int M = 3 ; // max number of slots to wait
+//const int lambda=782;
+//const int sigma=26;
+
+// formula min_backoff_after_success = min(s1=4?cd1:K+1,s2=4?cd2:K+1);
+// formula min_collisions = min(cd1,cd2);
+// formula max_collisions = max(cd1,cd2);
+
+//----------------------------------------------------------------------------------------------------------------------------
+// the bus
+module bus
+	
+	b : [0..2];
+	// b=0 - idle
+	// b=1 - active
+	// b=2 - collision
+	
+	// clocks of bus
+	y1 : [0..sigma+1]; // time since first send (used find time until channel sensed busy)
+	y2 : [0..sigma+1]; // time since second send (used to find time until collision detected)
+	
+	// a sender sends (ok - no other message being sent)
+	[send1] (b=0) -> (b'=1);
+	[send2] (b=0) -> (b'=1);
+	
+	// a sender sends (bus busy - collision)
+	[send1] (b=1|b=2) & (y1<sigma) -> (b'=2);
+	[send2] (b=1|b=2) & (y1<sigma) -> (b'=2);
+	
+	// finish sending
+	[end1] (b=1) -> (b'=0) & (y1'=0);
+	[end2] (b=1) -> (b'=0) & (y1'=0);
+	
+	// bus busy
+	[busy1] (b=1|b=2) & (y1>=sigma) -> (b'=b);  
+	[busy2] (b=1|b=2) & (y1>=sigma) -> (b'=b);  
+	
+	// collision detected
+	[cd] (b=2) & (y2<=sigma) -> (b'=0) & (y1'=0) & (y2'=0);
+	
+	// time passage
+	[time] (b=0) -> (y1'=0); // value of y1/y2 does not matter in state 0
+	[time] (b=1) -> (y1'=min(y1+1,sigma+1)); // no invariant in state 1
+	[time] (b=2) & (y2<sigma) -> (y1'=min(y1+1,sigma+1)) & (y2'=min(y2+1,sigma+1)); // invariant in state 2 (time until collision detected)
+	
+endmodule
+
+//----------------------------------------------------------------------------------------------------------------------------
+// model of first sender
+module station1
+	
+	// LOCAL STATE
+	s1 : [0..5];
+	// s1=0 - initial state
+	// s1=1 - transmit
+	// s1=2 - collision (set backoff)
+	// s1=3 - wait (bus busy)
+	// s1=4 - successfully sent
+	
+	// LOCAL CLOCK
+	x1 : [0..max(lambda,slot)];
+	
+	// BACKOFF COUNTER (number of slots to wait)
+	bc1 : [0..M];
+	
+	// COLLISION COUNTER
+	cd1 : [0..K];
+	
+	// start sending
+	[send1] (s1=0) -> (s1'=1) & (x1'=0); // start sending
+	[busy1] (s1=0) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // detects channel is busy so go into backoff
+	
+	// transmitting
+	[time] (s1=1) & (x1<lambda) -> (x1'=min(x1+1,lambda)); // let time pass
+	[end1]  (s1=1) & (x1=lambda) -> (s1'=4) & (x1'=0); // finished
+	[cd]   (s1=1) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // collision detected (increment backoff counter)
+	[cd] !(s1=1) -> (s1'=s1); // add loop for collision detection when not important
+	
+	// set backoff (no time can pass in this state)
+	// probability depends on which transmission this is (cd1)
+	[] s1=2 & cd1=1 ->  1/2 : (s1'=3) & (bc1'=0) + 1/2 : (s1'=3) & (bc1'=1) ;
+	[] s1=2 & cd1=2 ->  1/4 : (s1'=3) & (bc1'=0) + 1/4 : (s1'=3) & (bc1'=1) + 1/4 : (s1'=3) & (bc1'=2) + 1/4 : (s1'=3) & (bc1'=3) ;
+	
+	// wait until backoff counter reaches 0 then send again
+	[time] (s1=3) & (x1<slot) -> (x1'=x1+1); // let time pass (in slot)
+	[time] (s1=3) & (x1=slot) & (bc1>0) -> (x1'=1) & (bc1'=bc1-1); // let time pass (move slots)
+	[send1] (s1=3) & (x1=slot) & (bc1=0) -> (s1'=1) & (x1'=0); // finished backoff (bus appears free)
+	[busy1] (s1=3) & (x1=slot) & (bc1=0) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // finished backoff (bus busy)
+	
+	// once finished nothing matters
+	[time] (s1>=4) -> (x1'=0);
+
+endmodule
+
+//----------------------------------------------------------------------------------------------------------------------------
+
+// construct further stations through renaming
+module station2=station1[s1=s2,x1=x2,cd1=cd2,bc1=bc2,send1=send2,busy1=busy2,end1=end2] endmodule
+
+//----------------------------------------------------------------------------------------------------------------------------
+
+// reward structure for expected time
+rewards "time"
+	[time] true : 1;
+endrewards
+
+//----------------------------------------------------------------------------------------------------------------------------
+
+// labels/formulae
+label "all_delivered" = s1=4&s2=4;
+label "one_delivered" = s1=4|s2=4;
+label "collision_max_backoff" = (cd1=K & s1=1 & b=2)|(cd2=K & s2=1 & b=2);
+
diff --git a/test/functional/parser/prism/die.pm b/test/functional/parser/prism/die.pm
new file mode 100644
index 000000000..700951a05
--- /dev/null
+++ b/test/functional/parser/prism/die.pm
@@ -0,0 +1,24 @@
+// Knuth's model of a fair die using only fair coins
+dtmc
+
+module die
+
+	// local state
+	s : [0..7] init 0;
+	// value of the dice
+	d : [0..6] init 0;
+	
+	[] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2);
+	[] s=1 -> 0.5 : (s'=3) + 0.5 : (s'=4);
+	[] s=2 -> 0.5 : (s'=5) + 0.5 : (s'=6);
+	[] s=3 -> 0.5 : (s'=1) + 0.5 : (s'=7) & (d'=1);
+	[] s=4 -> 0.5 : (s'=7) & (d'=2) + 0.5 : (s'=7) & (d'=3);
+	[] s=5 -> 0.5 : (s'=7) & (d'=4) + 0.5 : (s'=7) & (d'=5);
+	[] s=6 -> 0.5 : (s'=2) + 0.5 : (s'=7) & (d'=6);
+	[] s=7 -> 1: (s'=7);
+	
+endmodule
+
+rewards "coin_flips"
+	[] s<7 : 1;
+endrewards
diff --git a/test/functional/parser/prism/firewire.nm b/test/functional/parser/prism/firewire.nm
new file mode 100644
index 000000000..26fa210b4
--- /dev/null
+++ b/test/functional/parser/prism/firewire.nm
@@ -0,0 +1,170 @@
+// firewire protocol with integer semantics
+// dxp/gxn 14/06/01
+
+// CLOCKS
+// x1 (x2) clock for node1 (node2)
+// y1 and y2 (z1 and z2) clocks for wire12 (wire21)
+mdp
+
+// maximum and minimum delays
+// fast
+const int rc_fast_max = 85;
+const int rc_fast_min = 76;
+// slow
+const int rc_slow_max = 167;
+const int rc_slow_min = 159;
+// delay caused by the wire length
+const int delay;
+// probability of choosing fast
+const double fast;
+const double slow=1-fast;
+
+module wire12
+	
+	// local state
+	w12 : [0..9];
+	// 0 - empty
+	// 1 -	rec_req
+	// 2 -  rec_req_ack
+	// 3 -	rec_ack
+	// 4 -	rec_ack_idle
+	// 5 -	rec_idle
+	// 6 -	rec_idle_req
+	// 7 -	rec_ack_req
+	// 8 -	rec_req_idle
+	// 9 -	rec_idle_ack
+	
+	// clock for wire12
+	y1 : [0..delay+1];
+	y2 : [0..delay+1];
+
+	// empty
+	// do not need y1 and y2 to increase as always reset when this state is left
+	// similarly can reset y1 and y2 when we re-enter this state
+	[snd_req12]  w12=0 -> (w12'=1) & (y1'=0) & (y2'=0);
+	[snd_ack12]  w12=0 -> (w12'=3) & (y1'=0) & (y2'=0);
+	[snd_idle12] w12=0 -> (w12'=5) & (y1'=0) & (y2'=0);
+	[time]       w12=0 -> (w12'=w12);	
+	// rec_req
+	[snd_req12]  w12=1 -> (w12'=1);
+	[rec_req12]  w12=1 -> (w12'=0) & (y1'=0) & (y2'=0);
+	[snd_ack12]  w12=1 -> (w12'=2) & (y2'=0);
+	[snd_idle12] w12=1 -> (w12'=8) & (y2'=0);
+	[time]       w12=1 & y2<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_req_ack
+	[snd_ack12] w12=2 -> (w12'=2);
+	[rec_req12] w12=2 -> (w12'=3);
+	[time]      w12=2 & y1<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_ack
+	[snd_ack12]  w12=3 -> (w12'=3);
+	[rec_ack12]  w12=3 -> (w12'=0) & (y1'=0) & (y2'=0);
+	[snd_idle12] w12=3 -> (w12'=4) & (y2'=0);
+	[snd_req12]  w12=3 -> (w12'=7) & (y2'=0);
+	[time]       w12=3 & y2<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_ack_idle
+	[snd_idle12] w12=4 -> (w12'=4);
+	[rec_ack12]  w12=4 -> (w12'=5);
+	[time]       w12=4 & y1<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_idle
+	[snd_idle12] w12=5 -> (w12'=5);
+	[rec_idle12] w12=5 -> (w12'=0) & (y1'=0) & (y2'=0);
+	[snd_req12]  w12=5 -> (w12'=6) & (y2'=0);
+	[snd_ack12]  w12=5 -> (w12'=9) & (y2'=0);
+	[time]       w12=5 & y2<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_idle_req
+	[snd_req12]  w12=6 -> (w12'=6);
+	[rec_idle12] w12=6 -> (w12'=1);
+	[time]       w12=6 & y1<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_ack_req
+	[snd_req12] w12=7 -> (w12'=7);
+	[rec_ack12] w12=7 -> (w12'=1);
+	[time]      w12=7 & y1<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_req_idle
+	[snd_idle12] w12=8 -> (w12'=8);
+	[rec_req12]  w12=8 -> (w12'=5);
+	[time]       w12=8 & y1<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	// rec_idle_ack
+	[snd_ack12]  w12=9 -> (w12'=9);
+	[rec_idle12] w12=9 -> (w12'=3);
+	[time]       w12=9 & y1<delay ->  (y1'=min(y1+1,delay+1)) & (y2'=min(y2+1,delay+1));
+	
+endmodule
+
+module node1
+	
+	// clock for node1
+	x1 : [0..168];
+	
+	// local state
+	s1 : [0..8];
+	// 0 - root contention
+	// 1 - rec_idle
+	// 2 - rec_req_fast
+	// 3 - rec_req_slow
+	// 4 - rec_idle_fast
+	// 5 - rec_idle_slow
+	// 6 - snd_req
+	// 7- almost_root
+	// 8 - almost_child
+	
+	// added resets to x1 when not considered again until after rest
+	// removed root and child (using almost root and almost child)
+	
+	// root contention immediate state)
+	[snd_idle12] s1=0 -> fast : (s1'=2) & (x1'=0) +  slow : (s1'=3) & (x1'=0);
+	[rec_idle21] s1=0 -> (s1'=1);
+	// rec_idle immediate state)
+	[snd_idle12] s1=1 -> fast : (s1'=4) & (x1'=0) +  slow : (s1'=5) & (x1'=0);
+	[rec_req21]  s1=1 -> (s1'=0);
+	// rec_req_fast
+	[rec_idle21] s1=2 -> (s1'=4);	
+	[snd_ack12]  s1=2 & x1>=rc_fast_min -> (s1'=7) & (x1'=0);
+	[time]       s1=2 & x1<rc_fast_max -> (x1'=min(x1+1,168));
+	// rec_req_slow
+	[rec_idle21] s1=3 -> (s1'=5);
+	[snd_ack12]  s1=3 & x1>=rc_slow_min -> (s1'=7) & (x1'=0);
+	[time]       s1=3 & x1<rc_slow_max -> (x1'=min(x1+1,168));
+	// rec_idle_fast
+	[rec_req21] s1=4 -> (s1'=2);
+	[snd_req12] s1=4 & x1>=rc_fast_min -> (s1'=6) & (x1'=0);
+	[time]      s1=4 & x1<rc_fast_max -> (x1'=min(x1+1,168));
+	// rec_idle_slow
+	[rec_req21] s1=5 -> (s1'=3);
+	[snd_req12] s1=5 & x1>=rc_slow_min -> (s1'=6) & (x1'=0);
+	[time]      s1=5 & x1<rc_slow_max -> (x1'=min(x1+1,168));
+	// snd_req 
+	// do not use x1 until reset (in state 0 or in state 1) so do not need to increase x1
+	// also can set x1 to 0 upon entering this state
+	[rec_req21] s1=6 -> (s1'=0);
+	[rec_ack21] s1=6 -> (s1'=8);
+	[time]      s1=6 -> (s1'=s1);
+	// almost root (immediate) 
+	// loop in final states to remove deadlock
+	[] s1=7 & s2=8 -> (s1'=s1);
+	[] s1=8 & s2=7 -> (s1'=s1);
+	[time] s1=7 -> (s1'=s1);
+	[time] s1=8 -> (s1'=s1);
+	
+endmodule
+
+// construct remaining automata through renaming
+module wire21=wire12[w12=w21, y1=z1, y2=z2, 
+	snd_req12=snd_req21, snd_idle12=snd_idle21, snd_ack12=snd_ack21,
+	rec_req12=rec_req21, rec_idle12=rec_idle21, rec_ack12=rec_ack21]
+endmodule
+module node2=node1[s1=s2, s2=s1, x1=x2, 
+	rec_req21=rec_req12, rec_idle21=rec_idle12, rec_ack21=rec_ack12,
+	snd_req12=snd_req21, snd_idle12=snd_idle21, snd_ack12=snd_ack21]
+endmodule
+
+// reward structures
+// time
+rewards "time"	
+	[time] true : 1;
+endrewards
+// time nodes sending
+rewards "time_sending"
+	[time] (w12>0 | w21>0) : 1;
+endrewards
+
+label "elected" = ((s1=8) & (s2=7)) | ((s1=7) & (s2=8));
\ No newline at end of file
diff --git a/test/functional/parser/prism/leader3.nm b/test/functional/parser/prism/leader3.nm
new file mode 100644
index 000000000..5a8cd34b5
--- /dev/null
+++ b/test/functional/parser/prism/leader3.nm
@@ -0,0 +1,96 @@
+// asynchronous leader election
+// 4 processes
+// gxn/dxp 29/01/01
+
+mdp
+
+const int N = 3; // number of processes
+
+//----------------------------------------------------------------------------------------------------------------------------
+module process1
+	
+	// COUNTER
+	c1 : [0..3-1];
+	
+	// STATES
+	s1 : [0..4];
+	// 0  make choice
+	// 1 have not received neighbours choice
+	// 2 active
+	// 3 inactive
+	// 4 leader
+	
+	// PREFERENCE
+	p1 : [0..1];
+	
+	// VARIABLES FOR SENDING AND RECEIVING
+	receive1 : [0..2];
+	// not received anything
+	// received choice
+	// received counter
+	sent1 : [0..2];
+	// not send anything
+	// sent choice
+	// sent counter
+	
+	// pick value
+	[] (s1=0) -> 0.5 : (s1'=1) & (p1'=0) + 0.5 : (s1'=1) & (p1'=1);
+	
+	// send preference
+	[p12] (s1=1) & (sent1=0) -> (sent1'=1);
+	// receive preference
+	// stay active
+	[p31] (s1=1) & (receive1=0) & !( (p1=0) & (p3=1) ) -> (s1'=2) & (receive1'=1);
+	// become inactive
+	[p31] (s1=1) & (receive1=0) & (p1=0) & (p3=1) -> (s1'=3) & (receive1'=1);
+	
+	// send preference (can now reset preference)
+	[p12] (s1=2) & (sent1=0) -> (sent1'=1) & (p1'=0);
+	// send counter (already sent preference)
+	// not received counter yet
+	[c12] (s1=2) & (sent1=1) & (receive1=1) -> (sent1'=2);
+	// received counter (pick again)
+	[c12] (s1=2) & (sent1=1) & (receive1=2) -> (s1'=0) & (p1'=0) & (c1'=0) & (sent1'=0) & (receive1'=0);
+	
+	// receive counter and not sent yet (note in this case do not pass it on as will send own counter)
+	[c31] (s1=2) & (receive1=1) & (sent1<2) -> (receive1'=2);
+	// receive counter and sent counter
+	// only active process (decide)
+	[c31] (s1=2) & (receive1=1) & (sent1=2) & (c3=N-1) -> (s1'=4) & (p1'=0) & (c1'=0) & (sent1'=0) & (receive1'=0);
+	// other active process (pick again)
+	[c31] (s1=2) & (receive1=1) & (sent1=2) & (c3<N-1) -> (s1'=0) & (p1'=0) & (c1'=0) & (sent1'=0) & (receive1'=0);
+	
+	// send preference (must have received preference) and can now reset
+	[p12] (s1=3) & (receive1>0) & (sent1=0) -> (sent1'=1) & (p1'=0);
+	// send counter (must have received counter first) and can now reset
+	[c12] (s1=3) & (receive1=2) & (sent1=1) ->  (s1'=3) & (p1'=0) & (c1'=0) & (sent1'=0) & (receive1'=0);
+	
+	// receive preference
+	[p31] (s1=3) & (receive1=0) -> (p1'=p3) & (receive1'=1);
+	// receive counter
+	[c31] (s1=3) & (receive1=1) & (c3<N-1) -> (c1'=c3+1) & (receive1'=2);
+		
+	// done
+	[done] (s1=4) -> (s1'=s1);
+	// add loop for processes who are inactive
+	[done] (s1=3) -> (s1'=s1);
+
+endmodule
+
+//----------------------------------------------------------------------------------------------------------------------------
+
+// construct further stations through renaming
+module process2=process1[s1=s2,p1=p2,c1=c2,sent1=sent2,receive1=receive2,p12=p23,p31=p12,c12=c23,c31=c12,p3=p1,c3=c1] endmodule
+module process3=process1[s1=s3,p1=p3,c1=c3,sent1=sent3,receive1=receive3,p12=p31,p31=p23,c12=c31,c31=c23,p3=p2,c3=c2] endmodule
+
+//----------------------------------------------------------------------------------------------------------------------------
+
+// reward - expected number of rounds (equals the number of times a process receives a counter)
+rewards "name"
+	[c12] true : 1;
+endrewards
+
+//----------------------------------------------------------------------------------------------------------------------------
+formula leaders = (s1=4?1:0)+(s2=4?1:0)+(s3=4?1:0);
+label "elected" = s1=4|s2=4|s3=4;
+
diff --git a/test/functional/parser/prism/leader3_5.pm b/test/functional/parser/prism/leader3_5.pm
new file mode 100644
index 000000000..0703e733d
--- /dev/null
+++ b/test/functional/parser/prism/leader3_5.pm
@@ -0,0 +1,85 @@
+// synchronous leader election protocol  (itai & Rodeh)
+// dxp/gxn 25/01/01
+
+dtmc
+
+// CONSTANTS
+const int N = 3; // number of processes
+const int K = 5; // range of probabilistic choice
+
+// counter module used to count the number of processes that have been read
+// and to know when a process has decided
+module counter
+	
+	// counter (c=i  means process j reading process (i-1)+j next)
+	c : [1..N-1];
+	
+	// reading
+	[read] c<N-1 -> 1:(c'=c+1);
+	// finished reading
+	[read] c=N-1 -> 1:(c'=c);
+	//decide
+	[done] u1|u2|u3 -> 1:(c'=c);
+	// pick again reset counter 
+	[retry] !(u1|u2|u3) -> 1:(c'=1);
+	// loop (when finished to avoid deadlocks)
+	[loop] s1=3 -> 1:(c'=c);
+	
+endmodule
+
+//  processes form a ring and suppose:
+// process 1 reads process 2
+// process 2 reads process 3
+// process 3 reads process 1
+module process1
+	
+	// local state
+	s1 : [0..3];
+	// s1=0 make random choice
+	// s1=1 reading
+	// s1=2 deciding
+	// s1=3 finished
+	
+	// has a unique id so far (initially true)
+	u1 : bool;
+	
+	// value to be sent to next process in the ring (initially sets this to its own value)
+	v1 : [0..K-1];
+	
+	// random choice
+	p1 : [0..K-1];
+	
+	// pick value
+	[pick] s1=0 -> 1/K : (s1'=1) & (p1'=0) & (v1'=0) & (u1'=true)
+	             + 1/K : (s1'=1) & (p1'=1) & (v1'=1) & (u1'=true)
+	             + 1/K : (s1'=1) & (p1'=2) & (v1'=2) & (u1'=true)
+	             + 1/K : (s1'=1) & (p1'=3) & (v1'=3) & (u1'=true)
+	             + 1/K : (s1'=1) & (p1'=4) & (v1'=4) & (u1'=true);
+	// read
+	[read] s1=1 &  u1 & c<N-1 -> 1:(u1'=(p1!=v2)) & (v1'=v2);
+	[read] s1=1 & !u1 & c<N-1 -> 1:(u1'=false) & (v1'=v2) & (p1'=0);
+	// read and move to decide
+	[read] s1=1 &  u1 & c=N-1 -> 1:(s1'=2) & (u1'=(p1!=v2)) & (v1'=0) & (p1'=0);
+	[read] s1=1 & !u1 & c=N-1 -> 1:(s1'=2) & (u1'=false) & (v1'=0);
+	// deciding
+	// done
+	[done] s1=2 -> 1:(s1'=3) & (u1'=false) & (v1'=0) & (p1'=0);
+	//retry
+	[retry] s1=2 -> 1:(s1'=0) & (u1'=false) & (v1'=0) & (p1'=0);
+	// loop (when finished to avoid deadlocks)
+	[loop] s1=3 -> 1:(s1'=3);
+	
+endmodule
+
+// construct remaining processes through renaming
+module process2 = process1 [ s1=s2,p1=p2,v1=v2,u1=u2,v2=v3 ] endmodule
+module process3 = process1 [ s1=s3,p1=p3,v1=v3,u1=u3,v2=v1 ] endmodule
+
+// expected number of rounds
+rewards "num_rounds"
+	[pick] true : 1;
+endrewards
+
+// labels
+label "elected" = s1=3&s2=3&s3=3;
+
diff --git a/test/functional/parser/prism/two_dice.nm b/test/functional/parser/prism/two_dice.nm
new file mode 100644
index 000000000..778153138
--- /dev/null
+++ b/test/functional/parser/prism/two_dice.nm
@@ -0,0 +1,40 @@
+// sum of two dice as the asynchronous parallel composition of
+// two copies of Knuth's model of a fair die using only fair coins
+
+mdp
+
+module die1
+
+	// local state
+	s1 : [0..7] init 0;
+	// value of the dice
+	d1 : [0..6] init 0;
+
+	[] s1=0 -> 0.5 : (s1'=1) + 0.5 : (s1'=2);
+	[] s1=1 -> 0.5 : (s1'=3) + 0.5 : (s1'=4);
+	[] s1=2 -> 0.5 : (s1'=5) + 0.5 : (s1'=6);
+	[] s1=3 -> 0.5 : (s1'=1) + 0.5 : (s1'=7) & (d1'=1);
+	[] s1=4 -> 0.5 : (s1'=7) & (d1'=2) + 0.5 : (s1'=7) & (d1'=3);
+	[] s1=5 -> 0.5 : (s1'=7) & (d1'=4) + 0.5 : (s1'=7) & (d1'=5);
+	[] s1=6 -> 0.5 : (s1'=2) + 0.5 : (s1'=7) & (d1'=6);
+	[] s1=7 & s2=7 -> 1: (s1'=7);
+endmodule
+
+module die2 = die1 [ s1=s2, s2=s1, d1=d2 ] endmodule
+
+rewards "coinflips"
+	[] s1<7 | s2<7 : 1;
+endrewards
+
+label "done" = s1=7 & s2=7;
+label "two" = s1=7 & s2=7 & d1+d2=2;
+label "three" = s1=7 & s2=7 & d1+d2=3;
+label "four" = s1=7 & s2=7 & d1+d2=4;
+label "five" = s1=7 & s2=7 & d1+d2=5;
+label "six" = s1=7 & s2=7 & d1+d2=6;
+label "seven" = s1=7 & s2=7 & d1+d2=7;
+label "eight" = s1=7 & s2=7 & d1+d2=8;
+label "nine" = s1=7 & s2=7 & d1+d2=9;
+label "ten" = s1=7 & s2=7 & d1+d2=10;
+label "eleven" = s1=7 & s2=7 & d1+d2=11;
+label "twelve" = s1=7 & s2=7 & d1+d2=12;
diff --git a/test/functional/parser/prism/wlan0_collide.nm b/test/functional/parser/prism/wlan0_collide.nm
new file mode 100644
index 000000000..1c14704e5
--- /dev/null
+++ b/test/functional/parser/prism/wlan0_collide.nm
@@ -0,0 +1,219 @@
+// WLAN PROTOCOL (two stations)
+// discrete time model
+// gxn/jzs 20/02/02
+
+mdp
+
+// COLLISIONS
+const int COL; // maximum number of collisions
+
+// TIMING CONSTRAINTS
+// we have used the FHSS parameters
+// then scaled by the value of ASLOTTIME
+const int ASLOTTIME = 1;
+const int DIFS = 3; // due to scaling can be either 2 or 3 which is modelled by a non-deterministic choice
+const int VULN = 1; // due to scaling can be either 0 or 1 which is modelled by a non-deterministic choice
+const int TRANS_TIME_MAX; // scaling up
+const int TRANS_TIME_MIN = 4; // scaling down
+const int ACK_TO = 6; 
+const int ACK = 4; // due to scaling can be either 3 or 4 which is modelled by a non-deterministic choice
+const int SIFS = 1; // due to scaling can be either 0 or 1 which is modelled by a non-deterministic choice
+// maximum constant used in timing constraints + 1
+const int TIME_MAX = max(ACK_TO,TRANS_TIME_MAX)+1;
+
+// CONTENTION WINDOW
+// CWMIN =15 & CWMAX =16
+// this means that MAX_BACKOFF IS 2
+const int MAX_BACKOFF = 0;
+
+//-----------------------------------------------------------------//
+// THE MEDIUM/CHANNEL
+
+// FORMULAE FOR THE CHANNEL
+// channel is busy
+formula busy = c1>0 | c2>0;
+// channel is free
+formula free = c1=0 & c2=0;
+
+module medium
+	
+	// number of collisions
+	col : [0..COL];
+	
+	// medium status 
+	c1 : [0..2];
+	c2 : [0..2];
+	// ci corresponds to messages associated with station i
+	// 0 nothing being sent
+	// 1 being sent correctly
+	// 2 being sent garbled	  
+	
+	// begin sending message and nothing else currently being sent
+	[send1] c1=0 & c2=0 -> (c1'=1);
+	[send2] c2=0 & c1=0 -> (c2'=1);
+	
+	// begin sending message and  something is already being sent
+	// in this case both messages become garbled
+	[send1] c1=0 & c2>0 -> (c1'=2) & (c2'=2) & (col'=min(col+1,COL));
+	[send2] c2=0 & c1>0 -> (c1'=2) & (c2'=2) & (col'=min(col+1,COL));
+	
+	// finish sending message
+	[finish1] c1>0 -> (c1'=0);
+	[finish2] c2>0 -> (c2'=0);
+
+endmodule
+
+//-----------------------------------------------------------------//
+// STATION 1
+module station1
+	// clock for station 1
+	x1 : [0..TIME_MAX];
+	
+	// local state
+	s1 : [1..12];
+	// 1 sense
+	// 2 wait until free before setting backoff
+	// 3 wait for DIFS then set slot
+	// 4 set backoff 
+	// 5 backoff
+	// 6 wait until free in backoff
+	// 7 wait for DIFS then resume backoff
+	// 8 vulnerable 
+	// 9 transmit
+	// 11 wait for SIFS and then ACK
+	// 10 wait for ACT_TO 
+	// 12 done
+	// BACKOFF
+	// separate into slots
+	slot1 : [0..1]; 
+	backoff1 : [0..15];
+	
+	// BACKOFF COUNTER
+	bc1 : [0..1];
+	// SENSE
+	// let time pass
+	[time] s1=1 & x1<DIFS & free -> (x1'=min(x1+1,TIME_MAX));
+	// ready to transmit
+	[] s1=1 & (x1=DIFS | x1=DIFS-1) -> (s1'=8) & (x1'=0);
+	// found channel busy so wait until free
+	[] s1=1 & busy -> (s1'=2) & (x1'=0);
+	// WAIT UNTIL FREE BEFORE SETTING BACKOFF
+	// let time pass (no need for the clock x1 to change)
+	[time] s1=2 & busy -> (s1'=2);
+	// find that channel is free so check its free for DIFS before setting backoff
+	[] s1=2 & free -> (s1'=3);
+	// WAIT FOR DIFS THEN SET BACKOFF
+	// let time pass
+	[time] s1=3 & x1<DIFS & free -> (x1'=min(x1+1,TIME_MAX));
+	// found channel busy so wait until free
+	[] s1=3 & busy -> (s1'=2) & (x1'=0);
+	// start backoff  first uniformly choose slot
+	// backoff counter 0
+	[] s1=3 & (x1=DIFS | x1=DIFS-1) & bc1=0 -> (s1'=4) & (x1'=0) & (slot1'=0) & (bc1'=min(bc1+1,MAX_BACKOFF));
+	// SET BACKOFF (no time can pass)
+	// chosen slot now set backoff
+	[] s1=4 -> 1/16 : (s1'=5) & (backoff1'=0 )
+	         + 1/16 : (s1'=5) & (backoff1'=1 )
+	         + 1/16 : (s1'=5) & (backoff1'=2 )
+	         + 1/16 : (s1'=5) & (backoff1'=3 )
+	         + 1/16 : (s1'=5) & (backoff1'=4 )
+	         + 1/16 : (s1'=5) & (backoff1'=5 )
+	         + 1/16 : (s1'=5) & (backoff1'=6 )
+	         + 1/16 : (s1'=5) & (backoff1'=7 )
+	         + 1/16 : (s1'=5) & (backoff1'=8 )
+	         + 1/16 : (s1'=5) & (backoff1'=9 )
+	         + 1/16 : (s1'=5) & (backoff1'=10)
+	         + 1/16 : (s1'=5) & (backoff1'=11)
+	         + 1/16 : (s1'=5) & (backoff1'=12)
+	         + 1/16 : (s1'=5) & (backoff1'=13)
+	         + 1/16 : (s1'=5) & (backoff1'=14)
+	         + 1/16 : (s1'=5) & (backoff1'=15);
+	// BACKOFF
+	// let time pass
+	[time] s1=5 & x1<ASLOTTIME & free -> (x1'=min(x1+1,TIME_MAX));
+	// decrement backoff
+	[] s1=5 & x1=ASLOTTIME & backoff1>0 -> (s1'=5) & (x1'=0) & (backoff1'=backoff1-1);	
+	[] s1=5 & x1=ASLOTTIME & backoff1=0 & slot1>0 -> (s1'=5) & (x1'=0) & (backoff1'=15) & (slot1'=slot1-1);	
+	// finish backoff 
+	[] s1=5 & x1=ASLOTTIME & backoff1=0 & slot1=0 -> (s1'=8) & (x1'=0);
+	// found channel busy
+	[] s1=5 & busy -> (s1'=6) & (x1'=0);
+	// WAIT UNTIL FREE IN BACKOFF
+	// let time pass (no need for the clock x1 to change)
+	[time] s1=6 & busy -> (s1'=6);
+	// find that channel is free
+	[] s1=6 & free -> (s1'=7);
+	
+	// WAIT FOR DIFS THEN RESUME BACKOFF
+	// let time pass
+	[time] s1=7 & x1<DIFS & free -> (x1'=min(x1+1,TIME_MAX));
+	// resume backoff (start again from previous backoff)
+	[] s1=7 & (x1=DIFS | x1=DIFS-1) -> (s1'=5) & (x1'=0);
+	// found channel busy
+	[] s1=7 & busy -> (s1'=6) & (x1'=0);
+	
+	// VULNERABLE
+	// let time pass
+	[time] s1=8 & x1<VULN -> (x1'=min(x1+1,TIME_MAX));
+	// move to transmit
+	[send1] s1=8 & (x1=VULN | x1=VULN-1) -> (s1'=9) & (x1'=0);
+	// TRANSMIT
+	// let time pass
+	[time] s1=9 & x1<TRANS_TIME_MAX -> (x1'=min(x1+1,TIME_MAX));
+	// finish transmission successful	
+	[finish1] s1=9 & x1>=TRANS_TIME_MIN & c1=1 -> (s1'=10) & (x1'=0);
+	// finish transmission garbled
+	[finish1] s1=9 & x1>=TRANS_TIME_MIN & c1=2 -> (s1'=11) & (x1'=0);
+	// WAIT FOR SIFS THEN WAIT FOR ACK
+	
+	// WAIT FOR SIFS i.e. c1=0
+	// check channel and busy: go into backoff
+	[] s1=10 & c1=0 & x1=0 & busy -> (s1'=2);
+	// check channel and free: let time pass
+	[time] s1=10 & c1=0 & x1=0 & free -> (x1'=min(x1+1,TIME_MAX));
+	// let time pass
+	// following guard is always false as SIFS=1
+	// [time] s1=10 & c1=0 & x1>0 & x1<SIFS -> (x1'=min(x1+1,TIME_MAX));
+	// ack is sent after SIFS (since SIFS-1=0 add condition that channel is free)
+	[send1] s1=10 & c1=0 & (x1=SIFS | (x1=SIFS-1 & free)) -> (s1'=10) & (x1'=0);
+	
+	// WAIT FOR ACK i.e. c1=1
+	// let time pass
+	[time] s1=10 & c1=1 & x1<ACK -> (x1'=min(x1+1,TIME_MAX));
+	// get acknowledgement so packet sent correctly and move to done
+	[finish1] s1=10 & c1=1 & (x1=ACK | x1=ACK-1) -> (s1'=12) & (x1'=0) & (bc1'=0);
+	
+	// WAIT FOR ACK_TO
+	// check channel and busy: go into backoff
+	[] s1=11 & x1=0 & busy -> (s1'=2);
+	// check channel and free: let time pass
+	[time] s1=11 & x1=0 & free -> (x1'=min(x1+1,TIME_MAX));
+	// let time pass
+	[time] s1=11 & x1>0 & x1<ACK_TO -> (x1'=min(x1+1,TIME_MAX));
+	// no acknowledgement (go to backoff waiting DIFS first)
+	[] s1=11 & x1=ACK_TO -> (s1'=3) & (x1'=0);
+		
+	// DONE
+	[time] s1=12 -> (s1'=12);
+
+endmodule	
+
+// ---------------------------------------------------------------------------- //
+// STATION 2 (rename STATION 1)
+module 
+station2=station1[x1=x2, 
+                  s1=s2,
+				  s2=s1,
+				  c1=c2,
+				  c2=c1, 
+				  slot1=slot2, 
+				  backoff1=backoff2, 
+				  bc1=bc2, 
+				  send1=send2, 
+				  finish1=finish2] 
+endmodule
+// ---------------------------------------------------------------------------- //
+
+label "twoCollisions" = col=2;
+label "fourCollisions" = col=4;
+label "sixCollisions" = col=6;
\ No newline at end of file

From 94b25c02cadde6fac5e89238f0ad0d1da24eb5b8 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Wed, 16 Apr 2014 21:18:12 +0200
Subject: [PATCH 078/147] Fixed bugs in some files. Made LTL a little better to
 compile under WIN32.

Former-commit-id: 71377f0672171b8dd8dbd9eb34425cc1de46ab4a
---
 CMakeLists.txt                                               | 3 +++
 .../ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp      | 2 +-
 .../ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp   | 2 +-
 src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h         | 2 +-
 src/modelchecker/prctl/SparseMdpPrctlModelChecker.h          | 2 +-
 src/parser/PrctlParser.cpp                                   | 2 +-
 src/parser/PrismParser.h                                     | 2 +-
 src/storage/expressions/SimpleValuation.h                    | 5 ++++-
 src/storage/prism/LocatedInformation.h                       | 1 +
 test/functional/solver/GmmxxLinearEquationSolverTest.cpp     | 2 +-
 test/functional/storage/ExpressionTest.cpp                   | 1 +
 11 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 77b5c64a0..c6d62bdde 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,6 +122,9 @@ elseif(MSVC)
 	# Windows.h breaks GMM in gmm_except.h because of its macro definition for min and max
 	add_definitions(/DNOMINMAX)
 	
+	# since nobody cares at the moment
+	add_definitions(/wd4250)
+	
 	if(ENABLE_Z3)
 		set(Z3_LIB_NAME "libz3")
 	endif()
diff --git a/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp b/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp
index f20e1eedb..55e55fbd2 100644
--- a/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp
+++ b/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp
@@ -31,7 +31,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || defined _WIN32
 #include <inttypes.h>
 typedef int8_t flex_int8_t;
 typedef uint8_t flex_uint8_t;
diff --git a/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp b/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp
index 82812c039..9be4a847a 100644
--- a/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp
+++ b/resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp
@@ -31,7 +31,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || defined _WIN32
 #include <inttypes.h>
 typedef int8_t flex_int8_t;
 typedef uint8_t flex_uint8_t;
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
index 2f03603d8..9d43dfb52 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
@@ -393,7 +393,7 @@ public:
 
 		// Perform the actual matrix-vector multiplication as long as the bound of the formula is met.
         if (linearEquationSolver != nullptr) {
-            this->linearEquationSolver->performMatrixVectorMultiplication(this->getModel().getTransitionMatrix(), result, &totalRewardVector, formula.getBound());
+			this->linearEquationSolver->performMatrixVectorMultiplication(this->getModel().getTransitionMatrix(), result, &totalRewardVector, static_cast<uint_fast64_t>(formula.getBound()));
         } else {
             throw storm::exceptions::InvalidStateException() << "No valid linear equation solver available.";
         }
diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
index 868f78722..c3e2aec58 100644
--- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
@@ -410,7 +410,7 @@ namespace storm {
                         result.resize(this->getModel().getNumberOfStates());
                     }
                     
-                    this->nondeterministicLinearEquationSolver->performMatrixVectorMultiplication(this->minimumOperatorStack.top(), this->getModel().getTransitionMatrix(), result, &totalRewardVector, formula.getBound());
+					this->nondeterministicLinearEquationSolver->performMatrixVectorMultiplication(this->minimumOperatorStack.top(), this->getModel().getTransitionMatrix(), result, &totalRewardVector, static_cast<uint_fast64_t>(formula.getBound()));
                     
                     return result;
                 }
diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp
index fb58d7ee9..d929c5ac7 100644
--- a/src/parser/PrctlParser.cpp
+++ b/src/parser/PrctlParser.cpp
@@ -140,7 +140,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl:
 		reachabilityReward = (qi::lit("F") > stateFormula)[qi::_val =
 				phoenix::new_<storm::property::prctl::ReachabilityReward<double>>(qi::_1)];
 		reachabilityReward.name("path formula (for reward operator)");
-		instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::double_)
+		instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::uint_)
 						[qi::_val = phoenix::new_<storm::property::prctl::InstantaneousReward<double>>(qi::_1)];
 		instantaneousReward.name("path formula (for reward operator)");
 		steadyStateReward = (qi::lit("S"))[qi::_val = phoenix::new_<storm::property::prctl::SteadyStateReward<double>>()];
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 3f8f17b65..db0ae9696 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -85,7 +85,7 @@ namespace storm {
                 }
             };
             
-            struct keywordsStruct : qi::symbols<char, bool> {
+            struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
                 keywordsStruct() {
                     add
                     ("dtmc", 1)
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 35b74291b..a196921a6 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -7,6 +7,7 @@
 #include <iostream>
 
 #include "src/storage/expressions/Valuation.h"
+#include "src/utility/OsDetection.h"
 
 namespace storm {
     namespace expressions {
@@ -23,8 +24,10 @@ namespace storm {
             // Instantiate some constructors and assignments with their default implementations.
             SimpleValuation(SimpleValuation const&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
-            SimpleValuation(SimpleValuation&&) = default;
+#ifndef WINDOWS            
+			SimpleValuation(SimpleValuation&&) = default;
             SimpleValuation& operator=(SimpleValuation&&) = default;
+#endif
             virtual ~SimpleValuation() = default;
 
             /*!
diff --git a/src/storage/prism/LocatedInformation.h b/src/storage/prism/LocatedInformation.h
index 8aa4d301e..81f5334b5 100644
--- a/src/storage/prism/LocatedInformation.h
+++ b/src/storage/prism/LocatedInformation.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_PRISM_LOCATEDINFORMATION_H_
 
 #include <string>
+#include <cstdint>
 
 #include "src/utility/OsDetection.h"
 
diff --git a/test/functional/solver/GmmxxLinearEquationSolverTest.cpp b/test/functional/solver/GmmxxLinearEquationSolverTest.cpp
index 077920f13..0381be434 100644
--- a/test/functional/solver/GmmxxLinearEquationSolverTest.cpp
+++ b/test/functional/solver/GmmxxLinearEquationSolverTest.cpp
@@ -81,7 +81,7 @@ TEST(GmmxxLinearEquationSolver, qmr) {
     
     ASSERT_NO_THROW(storm::solver::GmmxxLinearEquationSolver<double> solver(storm::solver::GmmxxLinearEquationSolver<double>::QMR, 1e-6, 10000, storm::solver::GmmxxLinearEquationSolver<double>::NONE));
     
-    storm::solver::GmmxxLinearEquationSolver<double> solver(storm::solver::GmmxxLinearEquationSolver<double>::QMR, 1e-6, 10000, storm::solver::GmmxxLinearEquationSolver<double>::NONE, 50);
+    storm::solver::GmmxxLinearEquationSolver<double> solver(storm::solver::GmmxxLinearEquationSolver<double>::QMR, 1e-6, 10000, storm::solver::GmmxxLinearEquationSolver<double>::NONE, true, 50);
     ASSERT_NO_THROW(solver.solveEquationSystem(A, x, b));
     ASSERT_LT(std::abs(x[0] - 1), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     ASSERT_LT(std::abs(x[1] - 3), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 0c19c5bfb..41556f6d6 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -1,4 +1,5 @@
 #include <map>
+#include <string>
 
 #include "gtest/gtest.h"
 #include "src/storage/expressions/Expression.h"

From 5a4730ae22ddc1ce0e2c5e515792b40da2579399 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 16 Apr 2014 22:41:46 +0200
Subject: [PATCH 079/147] When exporting DDs to the dot format, edges leading
 to the zero node are now suppressed. Also, nodes in the dot file are now
 labeled with variable names (+ the number of the bit).

Former-commit-id: 410d61d33331d5f9563172016aa8e9376509916c
---
 .../3rdparty/cudd-2.5.0/src/cudd/cuddExport.c | 19 ++++++++--
 src/storage/dd/CuddDd.cpp                     | 37 ++++++++++++++++++-
 src/storage/dd/CuddDd.h                       | 23 ++++++++----
 src/storage/dd/CuddDdManager.cpp              | 23 ++++++++++++
 src/storage/dd/CuddDdManager.h                |  7 ++++
 test/functional/storage/CuddDdTest.cpp        |  4 +-
 6 files changed, 99 insertions(+), 14 deletions(-)

diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddExport.c b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddExport.c
index 3d8da77ac..2392da36a 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddExport.c
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddExport.c
@@ -502,9 +502,11 @@ Cudd_DumpDot(
 	scan = nodelist[j];
 	while (scan != NULL) {
 	    if (st_is_member(visited,(char *) scan)) {
-		retval = fprintf(fp,"\"%p\";\n",
-		    (void *) ((mask & (ptrint) scan) / sizeof(DdNode)));
-		if (retval == EOF) goto failure;
+        if (scan != Cudd_ReadZero(dd)) {
+            retval = fprintf(fp,"\"%p\";\n",
+                                (void *) ((mask & (ptrint) scan) / sizeof(DdNode)));
+            if (retval == EOF) goto failure;
+        }
 	    }
 	    scan = scan->next;
 	}
@@ -541,6 +543,12 @@ Cudd_DumpDot(
 		scan = nodelist[j];
 		while (scan != NULL) {
 		    if (st_is_member(visited,(char *) scan)) {
+            retval = fprintf(fp,
+                    "\"%p\" [label = \"%s\"];\n",
+                    (void *) ((mask & (ptrint) scan) /
+                    sizeof(DdNode)), inames[dd->invperm[i]]);
+            if (retval == EOF) goto failure;
+            if (cuddT(scan) != Cudd_ReadZero(dd)) {
 			retval = fprintf(fp,
 			    "\"%p\" -> \"%p\";\n",
 			    (void *) ((mask & (ptrint) scan) /
@@ -548,6 +556,8 @@ Cudd_DumpDot(
 			    (void *) ((mask & (ptrint) cuddT(scan)) /
 			    sizeof(DdNode)));
 			if (retval == EOF) goto failure;
+            }
+            if (cuddE(scan) != Cudd_ReadZero(dd)) {
 			if (Cudd_IsComplement(cuddE(scan))) {
 			    retval = fprintf(fp,
 				"\"%p\" -> \"%p\" [style = dotted];\n",
@@ -565,6 +575,7 @@ Cudd_DumpDot(
 			}
 			if (retval == EOF) goto failure;
 		    }
+            }
 		    scan = scan->next;
 		}
 	    }
@@ -578,11 +589,13 @@ Cudd_DumpDot(
 	scan = nodelist[j];
 	while (scan != NULL) {
 	    if (st_is_member(visited,(char *) scan)) {
+        if (scan != Cudd_ReadZero(dd)) {
 		retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n",
 		    (void *) ((mask & (ptrint) scan) / sizeof(DdNode)),
 		    cuddV(scan));
 		if (retval == EOF) goto failure;
 	    }
+        }
 	    scan = scan->next;
 	}
     }
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 0e163c5f7..ef204f790 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -55,6 +55,10 @@ namespace storm {
             return result;
         }
         
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator-() const {
+            return this->getDdManager()->getZero() - *this;
+        }
+        
         Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator-=(Dd<DdType::CUDD> const& other) {
             this->cuddAdd -= other.getCuddAdd();
             
@@ -85,6 +89,12 @@ namespace storm {
             return result;
         }
         
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::logicalOr(Dd<DdType::CUDD> const& other) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Or(other.getCuddAdd()), metaVariableNames);
+        }
+        
         Dd<DdType::CUDD>& Dd<DdType::CUDD>::complement() {
             this->cuddAdd = ~this->cuddAdd;
             return *this;
@@ -230,7 +240,7 @@ namespace storm {
             this->cuddAdd = this->cuddAdd.SwapVariables(from, to);
         }
         
-        Dd<DdType::CUDD> Dd<DdType::CUDD>::multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) const {
             std::vector<ADD> summationDdVariables;
             
             // Create the CUDD summation variables.
@@ -358,9 +368,32 @@ namespace storm {
 			if (filename.empty()) {
 				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector);
             } else {
+                // Build the name input of the DD.
+                std::vector<char*> ddNames;
+                std::string ddName("f");
+                ddNames.push_back(new char[ddName.size() + 1]);
+                memcpy(ddNames.back(), ddName.c_str(), 2);
+                
+                // Now build the variables names.
+                std::vector<std::string> ddVariableNamesAsStrings = this->getDdManager()->getDdVariableNames();
+                std::vector<char*> ddVariableNames;
+                for (auto const& element : ddVariableNamesAsStrings) {
+                    ddVariableNames.push_back(new char[element.size() + 1]);
+                    memcpy(ddVariableNames.back(), element.c_str(), element.size() + 1);
+                }
+                
+                // Open the file, dump the DD and close it again.
                 FILE* filePointer = fopen(filename.c_str() , "w");
-				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, nullptr, nullptr, filePointer);
+				this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, &ddVariableNames[0], &ddNames[0], filePointer);
                 fclose(filePointer);
+                
+                // Finally, delete the names.
+                for (char* element : ddNames) {
+                    delete element;
+                }
+                for (char* element : ddVariableNames) {
+                    delete element;
+                }
             }
         }
         
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 6da2dc9c3..8ca99614a 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -88,6 +88,13 @@ namespace storm {
              */
             Dd<DdType::CUDD> operator-(Dd<DdType::CUDD> const& other) const;
             
+            /*!
+             * Subtracts the DD from the constant zero function.
+             *
+             * @return The resulting function represented as a DD.
+             */
+            Dd<DdType::CUDD> operator-() const;
+            
             /*!
              * Subtracts the given DD from the current one and assigns the result to the current DD.
              *
@@ -112,13 +119,6 @@ namespace storm {
              */
             Dd<DdType::CUDD>& operator/=(Dd<DdType::CUDD> const& other);
             
-            /*!
-             * Subtracts the DD from the constant zero function.
-             *
-             * @return The resulting function represented as a DD.
-             */
-            Dd<DdType::CUDD> minus() const;
-            
             /*!
              * Retrieves the logical complement of the current DD. The result will map all encodings with a value
              * unequal to zero to false and all others to true.
@@ -126,6 +126,13 @@ namespace storm {
              * @return The logical complement of the current DD.
              */
             Dd<DdType::CUDD> operator~() const;
+
+            /*!
+             * Performs a logical or of the current and the given DD.
+             *
+             * @return The logical or of the operands.
+             */
+            Dd<DdType::CUDD> logicalOr(Dd<DdType::CUDD> const& other) const;
             
             /*!
              * Logically complements the current DD. The result will map all encodings with a value
@@ -232,7 +239,7 @@ namespace storm {
              * matrix multiplication.
              * @return A DD representing the result of the matrix-matrix multiplication.
              */
-            Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames);
+            Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) const;
             
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 9843b5c92..cda474e7f 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -1,4 +1,5 @@
 #include <cmath>
+#include <string>
 #include <algorithm>
 
 #include "src/storage/dd/CuddDdManager.h"
@@ -179,5 +180,27 @@ namespace storm {
         Cudd& DdManager<DdType::CUDD>::getCuddManager() {
             return this->cuddManager;
         }
+        
+        std::vector<std::string> DdManager<DdType::CUDD>::getDdVariableNames() const {
+            // First, we initialize a list DD variables and their names.
+            std::vector<std::pair<ADD, std::string>> variableNamePairs;
+            for (auto const& nameMetaVariablePair : this->metaVariableMap) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = nameMetaVariablePair.second;
+                for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
+                    variableNamePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getCuddAdd(), metaVariable.getName() + "." + std::to_string(variableIndex));
+                }
+            }
+            
+            // Then, we sort this list according to the indices of the ADDs.
+            std::sort(variableNamePairs.begin(), variableNamePairs.end(), [](std::pair<ADD, std::string> const& a, std::pair<ADD, std::string> const& b) { return a.first.getNode()->index < b.first.getNode()->index; });
+            
+            // Now, we project the sorted vector to its second component.
+            std::vector<std::string> result;
+            for (auto const& element : variableNamePairs) {
+                result.push_back(element.second);
+            }
+            
+            return result;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index ca3f9c2c3..96daeb34a 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -131,6 +131,13 @@ namespace storm {
             bool hasMetaVariable(std::string const& metaVariableName) const;
             
         private:
+            /*!
+             * Retrieves a list of names of the DD variables in the order of their index.
+             *
+             * @return A list of DD variable names.
+             */
+            std::vector<std::string> getDdVariableNames() const;
+            
             /*!
              * Retrieves the underlying CUDD manager.
              *
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 8a5be849a..01d40164a 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -150,6 +150,9 @@ TEST(CuddDd, OperatorTest) {
     
     dd1 = ~dd3;
     EXPECT_TRUE(dd1 == manager->getOne());
+
+    dd3 = dd1.logicalOr(dd2);
+    EXPECT_TRUE(dd3 == manager->getOne());
     
     dd1 = manager->getIdentity("x");
     dd2 = manager->getConstant(5);
@@ -253,7 +256,6 @@ TEST(CuddDd, GetSetValueTest) {
     storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne();
     ASSERT_NO_THROW(dd1.setValue("x", 4, 2));
     EXPECT_EQ(2, dd1.getLeafCount());
-    dd1.exportToDot("dd1.dot");
     
     std::map<std::string, int_fast64_t> metaVariableToValueMap;
     metaVariableToValueMap.emplace("x", 1);

From 61d4bb956c01437662c1d11fbf72d5cb19dd0c77 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 17 Apr 2014 10:49:01 +0200
Subject: [PATCH 080/147] Added functionality to compare two ADDs up to a given
 precision. Added logical operator overloads to DD interface. Added tests for
 all new features.

Former-commit-id: 738ad49d62089c5ebf6058abdb182f180d154be4
---
 resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h |  1 +
 .../3rdparty/cudd-2.5.0/src/cudd/cuddSat.c    | 65 +++++++++++++++++++
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.cc    | 10 +++
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.hh    |  4 +-
 src/storage/dd/CuddDd.cpp                     | 20 +++++-
 src/storage/dd/CuddDd.h                       | 34 +++++++---
 src/storage/dd/CuddDdManager.cpp              |  4 +-
 test/functional/storage/CuddDdTest.cpp        | 16 +++--
 8 files changed, 136 insertions(+), 18 deletions(-)

diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h b/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
index 5a2c2f952..51d509b35 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
@@ -964,6 +964,7 @@ extern DdNode * Cudd_Increasing (DdManager *dd, DdNode *f, int i);
 extern int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D);
 extern int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D);
 extern int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr);
+extern int Cudd_EqualSupNormRel (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr);
 extern DdNode * Cudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f);
 extern DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f);
 extern DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd);
diff --git a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddSat.c b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddSat.c
index 19dcafff0..869733f32 100644
--- a/resources/3rdparty/cudd-2.5.0/src/cudd/cuddSat.c
+++ b/resources/3rdparty/cudd-2.5.0/src/cudd/cuddSat.c
@@ -853,6 +853,71 @@ Cudd_EqualSupNorm(
 
 } /* end of Cudd_EqualSupNorm */
 
+/**Function********************************************************************
+ 
+ Synopsis    [Compares two ADDs for equality within tolerance.]
+ 
+ Description [Same as Cudd_EqualSupNorm but tests for max _relative_ difference
+ i.e. (f-g/f)<e instead of (f-g)<e ]
+ 
+ SideEffects [None]
+ 
+ SeeAlso     []
+ 
+ ******************************************************************************/
+int
+Cudd_EqualSupNormRel(
+                     DdManager * dd /* manager */,
+                     DdNode * f /* first ADD */,
+                     DdNode * g /* second ADD */,
+                     CUDD_VALUE_TYPE  tolerance /* maximum allowed difference */,
+                     int  pr /* verbosity level */)
+{
+    DdNode *fv, *fvn, *gv, *gvn, *r;
+    unsigned int topf, topg;
+    
+    statLine(dd);
+    /* Check terminal cases. */
+    if (f == g) return(1);
+    if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
+        if (ddAbs((cuddV(f) - cuddV(g))/cuddV(f)) < tolerance) {
+            return(1);
+        } else {
+            if (pr>0) {
+                (void) fprintf(dd->out,"Offending nodes:\n");
+                (void) fprintf(dd->out,
+                               "f: address = %p\t value = %40.30f\n",
+                               (void *) f, cuddV(f));
+                (void) fprintf(dd->out,
+                               "g: address = %p\t value = %40.30f\n",
+                               (void *) g, cuddV(g));
+            }
+            return(0);
+        }
+    }
+    
+    /* We only insert the result in the cache if the comparison is
+     ** successful. Therefore, if we hit we return 1. */
+    r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNormRel,f,g);
+    if (r != NULL) {
+        return(1);
+    }
+    
+    /* Compute the cofactors and solve the recursive subproblems. */
+    topf = cuddI(dd,f->index);
+    topg = cuddI(dd,g->index);
+    
+    if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
+    if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
+    
+    if (!Cudd_EqualSupNormRel(dd,fv,gv,tolerance,pr)) return(0);
+    if (!Cudd_EqualSupNormRel(dd,fvn,gvn,tolerance,pr)) return(0);
+    
+    cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNormRel,f,g,DD_ONE(dd));
+    
+    return(1);
+    
+} /* end of Cudd_EqualSupNormRel */
 
 /**Function********************************************************************
 
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
index c9fcf7b11..2753c0950 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
@@ -4747,6 +4747,16 @@ ADD::EqualSupNorm(
 
 } // ADD::EqualSupNorm
 
+bool
+ADD::EqualSupNormRel(
+  const ADD& g,
+  CUDD_VALUE_TYPE tolerance,
+  int pr) const
+{
+    DdManager *mgr = checkSameManager(g);
+    return Cudd_EqualSupNormRel(mgr, node, g.node, tolerance, pr) != 0;
+    
+} // ADD::EqualSupNormRel
 
 BDD
 BDD::MakePrime(
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
index a1a859490..795a7a2ee 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
@@ -426,8 +426,8 @@ public:
     ADD TimesPlus(const ADD& B, std::vector<ADD> z) const;
     ADD Triangle(const ADD& g, std::vector<ADD> z) const;
     ADD Eval(int * inputs) const;
-    bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr) const;
-
+    bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr = 0) const;
+    bool EqualSupNormRel(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr = 0) const;
 }; // ADD
 
 
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index ef204f790..c5fb92bbd 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -83,13 +83,21 @@ namespace storm {
             return *this;
         }
         
-        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator~() const {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator!() const {
             Dd<DdType::CUDD> result(*this);
             result.complement();
             return result;
         }
+
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator&&(Dd<DdType::CUDD> const& other) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            
+            // Rewrite a and b to not((not a) or (not b)). 
+            return Dd<DdType::CUDD>(this->getDdManager(), ~(~this->getCuddAdd()).Or(~other.getCuddAdd()), metaVariableNames);
+        }
         
-        Dd<DdType::CUDD> Dd<DdType::CUDD>::logicalOr(Dd<DdType::CUDD> const& other) const {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::operator||(Dd<DdType::CUDD> const& other) const {
             std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
             metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
             return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Or(other.getCuddAdd()), metaVariableNames);
@@ -204,6 +212,14 @@ namespace storm {
             this->cuddAdd = this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd());
         }
         
+        bool Dd<DdType::CUDD>::equalModuloPrecision(Dd<DdType::CUDD> const& other, double precision, bool relative) const {
+            if (relative) {
+                return this->getCuddAdd().EqualSupNormRel(other.getCuddAdd(), precision);
+            } else {
+                return this->getCuddAdd().EqualSupNorm(other.getCuddAdd(), precision);
+            }
+        }
+        
         void Dd<DdType::CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
             std::vector<ADD> from;
             std::vector<ADD> to;
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 8ca99614a..1942f6504 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -48,6 +48,20 @@ namespace storm {
              */
             bool operator!=(Dd<DdType::CUDD> const& other) const;
             
+            /*!
+             * Performs a logical or of the current and the given DD.
+             *
+             * @return The logical or of the operands.
+             */
+            Dd<DdType::CUDD> operator||(Dd<DdType::CUDD> const& other) const;
+            
+            /*!
+             * Performs a logical and of the current and the given DD.
+             *
+             * @return The logical and of the operands.
+             */
+            Dd<DdType::CUDD> operator&&(Dd<DdType::CUDD> const& other) const;
+            
             /*!
              * Adds the two DDs.
              *
@@ -125,14 +139,7 @@ namespace storm {
              *
              * @return The logical complement of the current DD.
              */
-            Dd<DdType::CUDD> operator~() const;
-
-            /*!
-             * Performs a logical or of the current and the given DD.
-             *
-             * @return The logical or of the operands.
-             */
-            Dd<DdType::CUDD> logicalOr(Dd<DdType::CUDD> const& other) const;
+            Dd<DdType::CUDD> operator!() const;
             
             /*!
              * Logically complements the current DD. The result will map all encodings with a value
@@ -222,6 +229,17 @@ namespace storm {
              */
             void maxAbstract(std::set<std::string> const& metaVariableNames);
             
+            /*!
+             * Checks whether the current and the given DD represent the same function modulo some given precision.
+             *
+             * @param other The DD with which to compare.
+             * @param precision An upper bound on the maximal difference between any two function values that is to be
+             * tolerated.
+             * @param relative If set to true, not the absolute values have to be within the precision, but the relative
+             * values.
+             */
+            bool equalModuloPrecision(Dd<DdType::CUDD> const& other, double precision, bool relative = true) const;
+            
             /*!
              * Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
              * the same number of underlying DD variables.
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index cda474e7f..4352e52b7 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -45,14 +45,14 @@ namespace storm {
             if (value & (1ull << (ddVariables.size() - 1))) {
                 result = ddVariables[0];
             } else {
-                result = ~ddVariables[0];
+                result = !ddVariables[0];
             }
             
             for (std::size_t i = 1; i < ddVariables.size(); ++i) {
                 if (value & (1ull << (ddVariables.size() - i - 1))) {
                     result *= ddVariables[i];
                 } else {
-                    result *= ~ddVariables[i];
+                    result *= !ddVariables[i];
                 }
             }
                         
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 01d40164a..c405006d8 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -130,9 +130,12 @@ TEST(CuddDd, OperatorTest) {
     dd3 += manager->getZero();
     EXPECT_TRUE(dd3 == manager->getConstant(2));
     
+    dd3 = dd1 && manager->getConstant(3);
+    EXPECT_TRUE(dd1 == manager->getOne());
+
     dd3 = dd1 * manager->getConstant(3);
     EXPECT_TRUE(dd3 == manager->getConstant(3));
-    
+
     dd3 *= manager->getConstant(2);
     EXPECT_TRUE(dd3 == manager->getConstant(6));
     
@@ -148,10 +151,10 @@ TEST(CuddDd, OperatorTest) {
     dd3.complement();
     EXPECT_TRUE(dd3 == manager->getZero());
     
-    dd1 = ~dd3;
+    dd1 = !dd3;
     EXPECT_TRUE(dd1 == manager->getOne());
 
-    dd3 = dd1.logicalOr(dd2);
+    dd3 = dd1 || dd2;
     EXPECT_TRUE(dd3 == manager->getOne());
     
     dd1 = manager->getIdentity("x");
@@ -161,7 +164,7 @@ TEST(CuddDd, OperatorTest) {
     EXPECT_EQ(1, dd3.getNonZeroCount());
     
     storm::dd::Dd<storm::dd::DdType::CUDD> dd4 = dd1.notEquals(dd2);
-    EXPECT_TRUE(dd4 == ~dd3);
+    EXPECT_TRUE(dd4 == !dd3);
     
     dd3 = dd1.less(dd2);
     EXPECT_EQ(11, dd3.getNonZeroCount());
@@ -174,6 +177,11 @@ TEST(CuddDd, OperatorTest) {
 
     dd3 = dd1.greaterOrEqual(dd2);
     EXPECT_EQ(5, dd3.getNonZeroCount());
+    
+    dd1 = manager->getConstant(0.01);
+    dd2 = manager->getConstant(0.01 + 1e-6);
+    EXPECT_TRUE(dd1.equalModuloPrecision(dd2, 1e-6, false));
+    EXPECT_FALSE(dd1.equalModuloPrecision(dd2, 1e-6));
 }
 
 TEST(CuddDd, AbstractionTest) {

From 5fe7ffe51a44c32365ecec69b1cfb865c3b879c2 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 17 Apr 2014 17:09:19 +0200
Subject: [PATCH 081/147] Added missing function declaration in CUDD'c C++
 interface. Started on an iterator for DD valuations.

Former-commit-id: a97ccdec3d31a67bde210a2c70615cdfae7135a6
---
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.cc    |  6 +--
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.hh    |  1 +
 src/storage/dd/CuddDd.cpp                     |  1 +
 src/storage/dd/CuddDd.h                       |  2 +-
 src/storage/dd/CuddDdForwardIterator.cpp      | 33 +++++++++++++
 src/storage/dd/CuddDdForwardIterator.h        | 46 +++++++++++++++++++
 src/storage/dd/DdForwardIterator.h            | 13 ++++++
 7 files changed, 98 insertions(+), 4 deletions(-)
 create mode 100644 src/storage/dd/CuddDdForwardIterator.cpp
 create mode 100644 src/storage/dd/CuddDdForwardIterator.h
 create mode 100644 src/storage/dd/DdForwardIterator.h

diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
index 2753c0950..d62328ff0 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
@@ -5277,14 +5277,14 @@ ABDD::FirstCube(
 
 
 int
-NextCube(
+ABDD::NextCube(
   DdGen * gen,
   int ** cube,
-  CUDD_VALUE_TYPE * value)
+  CUDD_VALUE_TYPE * value) const
 {
     return Cudd_NextCube(gen, cube, value);
 
-} // NextCube
+} // ABDD::NextCube
 
 
 BDD
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
index 795a7a2ee..d8c2d0722 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
@@ -192,6 +192,7 @@ public:
 	const;
     int CountLeaves() const;
     DdGen * FirstCube(int ** cube, CUDD_VALUE_TYPE * value) const;
+    int NextCube(DdGen * gen, int ** cube, CUDD_VALUE_TYPE * value) const;
     double Density(int nvars) const;
 
 }; // ABDD
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index c5fb92bbd..313a2b4d8 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -1,3 +1,4 @@
+#include <cstring>
 #include <algorithm>
 
 #include "src/storage/dd/CuddDd.h"
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 1942f6504..fa780f263 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -20,7 +20,7 @@ namespace storm {
         template<>
         class Dd<DdType::CUDD> {
         public:
-            // Declare the DdManager class as friend so it can access the internals of a DD.
+            // Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
             friend class DdManager<DdType::CUDD>;
             
             // Instantiate all copy/move constructors/assignments with the default implementation.
diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp
new file mode 100644
index 000000000..fc66895dd
--- /dev/null
+++ b/src/storage/dd/CuddDdForwardIterator.cpp
@@ -0,0 +1,33 @@
+#include "src/storage/dd/CuddDdForwardIterator.h"
+
+namespace storm {
+    namespace dd {
+        DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd) : ddManager(ddManager), value(0), cube(nullptr), cuddAdd(cuddAdd), isAtEnd(false), generator(nullptr) {
+            // Start by getting the first cube.
+            this->generator = this->cuddAdd.FirstCube(&cube, &value);
+            
+            // If the generator is already empty, we set the corresponding flag.
+            this->isAtEnd = Cudd_IsGenEmpty(generator);
+        }
+        
+        DdForwardIterator<DdType::CUDD>& DdForwardIterator<DdType::CUDD>::operator++() {
+            // TODO: eliminate current
+        }
+        
+        bool DdForwardIterator<DdType::CUDD>::operator==(DdForwardIterator<DdType::CUDD> const& other) const {
+            if (this->isAtEnd && other.isAtEnd) {
+                return true;
+            } else {
+                return this->cuddAdd == other.cuddAdd;
+            }
+        }
+        
+        bool DdForwardIterator<DdType::CUDD>::operator!=(DdForwardIterator<DdType::CUDD> const& other) const {
+            return !(*this == other);
+        }
+        
+        storm::expressions::SimpleValuation DdForwardIterator<DdType::CUDD>::operator*() const {
+            // FIXME: construct valuation and return it.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdForwardIterator.h b/src/storage/dd/CuddDdForwardIterator.h
new file mode 100644
index 000000000..09c627b14
--- /dev/null
+++ b/src/storage/dd/CuddDdForwardIterator.h
@@ -0,0 +1,46 @@
+#ifndef STORM_STORAGE_DD_CUDDDDFORWARDITERATOR_H_
+#define STORM_STORAGE_DD_CUDDDDFORWARDITERATOR_H_
+
+#include <memory>
+#include <cstdint>
+
+#include "src/storage/dd/DdForwardIterator.h"
+#include "src/storage/expressions/SimpleValuation.h"
+
+// Include the C++-interface of CUDD.
+#include "cuddObj.hh"
+
+namespace storm {
+    namespace dd {
+        template<>
+        class DdForwardIterator<DdType::CUDD> {
+        public:
+            // Forward-declare the DdManager class.
+            template<DdType Type> class DdManager;
+            
+            DdForwardIterator<DdType::CUDD>& operator++();
+            storm::expressions::SimpleValuation operator*() const;
+            bool operator==(DdForwardIterator<DdType::CUDD> const& other) const;
+            bool operator!=(DdForwardIterator<DdType::CUDD> const& other) const;
+            
+        private:
+            DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::vector<ADD> const& relevantDdVariables);
+            
+            std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
+            
+            double value;
+            
+            int* cube;
+            
+            uint_fast64_t positionInCube;
+
+            ADD cuddAdd;
+            
+            bool isAtEnd;
+            
+            DdGen* generator;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_CUDDDDFORWARDITERATOR_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/DdForwardIterator.h b/src/storage/dd/DdForwardIterator.h
new file mode 100644
index 000000000..2eed23090
--- /dev/null
+++ b/src/storage/dd/DdForwardIterator.h
@@ -0,0 +1,13 @@
+#ifndef STORM_STORAGE_DD_DDFORWARDITERATOR_H_
+#define STORM_STORAGE_DD_DDFORWARDITERATOR_H_
+
+#include "src/storage/dd/DdType.h"
+
+namespace storm {
+    namespace dd {
+        // Declare DdIterator class so we can then specialize it for the different DD types.
+        template<DdType Type> class DdForwardIterator;
+    }
+}
+
+#endif /* STORM_STORAGE_DD_DDFORWARDITERATOR_H_ */
\ No newline at end of file

From 3940dbf45c47935f064e1317e6f9c969900929af Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 17 Apr 2014 17:17:42 +0200
Subject: [PATCH 082/147] Accessing index of node via method interface, not
 member access.

Former-commit-id: d53006d5d44fe4ec52fbbdebeba58737466ed262
---
 src/storage/dd/CuddDdManager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 4352e52b7..2d77c6350 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -192,7 +192,7 @@ namespace storm {
             }
             
             // Then, we sort this list according to the indices of the ADDs.
-            std::sort(variableNamePairs.begin(), variableNamePairs.end(), [](std::pair<ADD, std::string> const& a, std::pair<ADD, std::string> const& b) { return a.first.getNode()->index < b.first.getNode()->index; });
+            std::sort(variableNamePairs.begin(), variableNamePairs.end(), [](std::pair<ADD, std::string> const& a, std::pair<ADD, std::string> const& b) { return a.first.NodeReadIndex() < b.first.NodeReadIndex(); });
             
             // Now, we project the sorted vector to its second component.
             std::vector<std::string> result;

From 311247ff0cba4b8a38637ce5e8daa5703a9e4422 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 17 Apr 2014 18:30:57 +0200
Subject: [PATCH 083/147] Added support for Xor in expression classes and added
 parsing functionality for Xor, Implies and Iff.

Former-commit-id: 16e023cf26806e7d9c6c7f72073b77bfff975d61
---
 src/parser/PrismParser.cpp                    | 28 +++++++++++++++++--
 src/parser/PrismParser.h                      |  8 ++++--
 .../BinaryBooleanFunctionExpression.cpp       |  3 ++
 .../BinaryBooleanFunctionExpression.h         |  2 +-
 src/storage/expressions/Expression.cpp        |  5 ++++
 src/storage/expressions/Expression.h          |  1 +
 test/functional/parser/PrismParserTest.cpp    |  2 +-
 test/functional/storage/ExpressionTest.cpp    |  6 ++++
 8 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 6039c2c11..f46b3f691 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -91,10 +91,10 @@ namespace storm {
             relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createNotEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
             relativeExpression.name("relative expression");
             
-            andExpression = relativeExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> relativeExpression)[qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
+            andExpression = relativeExpression[qi::_val = qi::_1] >> *((qi::lit("&")[qi::_a = storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And] | qi::lit("<=>")[qi::_a = storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff] | qi::lit("^")[qi::_a = storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Xor]) >> relativeExpression)[phoenix::if_(qi::_a == storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And) [ qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [ phoenix::if_(qi::_a == storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff) [ qi::_val = phoenix::bind(&PrismParser::createIffExpression, phoenix::ref(*this), qi::_val, qi::_1) ] .else_ [ qi::_val = phoenix::bind(&PrismParser::createXorExpression, phoenix::ref(*this), qi::_val, qi::_1) ] ] ];
             andExpression.name("and expression");
             
-            orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&PrismParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)];
+            orExpression = andExpression[qi::_val = qi::_1] >> *((qi::lit("|")[qi::_a = true] | qi::lit("=>")[qi::_a = false]) >> andExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createImpliesExpression, phoenix::ref(*this), qi::_val, qi::_1)] ];
             orExpression.name("or expression");
             
             iteExpression = orExpression[qi::_val = qi::_1] >> -(qi::lit("?") > orExpression > qi::lit(":") > orExpression)[qi::_val = phoenix::bind(&PrismParser::createIteExpression, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
@@ -271,6 +271,14 @@ namespace storm {
             }
         }
         
+        storm::expressions::Expression PrismParser::createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1.implies(e2);
+            }
+        }
+        
         storm::expressions::Expression PrismParser::createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
@@ -319,6 +327,22 @@ namespace storm {
             }
         }
         
+        storm::expressions::Expression PrismParser::createIffExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1.iff(e2);
+            }
+        }
+        
+        storm::expressions::Expression PrismParser::createXorExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (!this->secondRun) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return e1 ^ e2;
+            }
+        }
+        
         storm::expressions::Expression PrismParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 3f8f17b65..de3effa32 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -25,6 +25,7 @@ typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost:
 
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/Expressions.h"
 #include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
@@ -244,8 +245,8 @@ namespace storm {
             // Rules for parsing a composed expression.
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> iteExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> orExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> orExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<storm::expressions::BinaryBooleanFunctionExpression::OperatorType>, Skipper> andExpression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
@@ -269,12 +270,15 @@ namespace storm {
             bool addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
             
             storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const;
+            storm::expressions::Expression createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createIffExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createXorExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index 9f5e5edeb..d5d6694ab 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -23,6 +23,7 @@ namespace storm {
             switch (this->getOperatorType()) {
                 case OperatorType::And: result = firstOperandEvaluation && secondOperandEvaluation; break;
                 case OperatorType::Or: result = firstOperandEvaluation || secondOperandEvaluation; break;
+                case OperatorType::Xor: result = firstOperandEvaluation ^ secondOperandEvaluation; break;
                 case OperatorType::Implies: result = !firstOperandEvaluation || secondOperandEvaluation; break;
                 case OperatorType::Iff: result = (firstOperandEvaluation && secondOperandEvaluation) || (!firstOperandEvaluation && !secondOperandEvaluation); break;
             }
@@ -55,6 +56,7 @@ namespace storm {
                     return firstOperandSimplified;
                 }
                 break;
+                case OperatorType::Xor: break;
                 case OperatorType::Implies: if (firstOperandSimplified->isTrue()) {
                     return secondOperandSimplified;
                 } else if (firstOperandSimplified->isFalse()) {
@@ -88,6 +90,7 @@ namespace storm {
             switch (this->getOperatorType()) {
                 case OperatorType::And: stream << " & "; break;
                 case OperatorType::Or: stream << " | "; break;
+                case OperatorType::Xor: stream << " ^ "; break;
                 case OperatorType::Implies: stream << " => "; break;
                 case OperatorType::Iff: stream << " <=> "; break;
             }
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index 7a05a1ab5..8b1bb7437 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -11,7 +11,7 @@ namespace storm {
             /*!
              * An enum type specifying the different operators applicable.
              */
-            enum class OperatorType {And, Or, Implies, Iff};
+            enum class OperatorType {And, Or, Xor, Implies, Iff};
             
             /*!
              * Creates a binary boolean function expression with the given return type, operands and operator.
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 7eb94966b..5b5a2bfb6 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -166,6 +166,11 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Divide)));
         }
         
+        Expression Expression::operator^(Expression const& other) const {
+            LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '^' requires boolean operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Xor)));
+        }
+        
         Expression Expression::operator&&(Expression const& other) const {
             LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '&&' requires boolean operands.");
             return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::And)));
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index ea7d99572..d751dfbb9 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -47,6 +47,7 @@ namespace storm {
             Expression operator-() const;
             Expression operator*(Expression const& other) const;
             Expression operator/(Expression const& other) const;
+            Expression operator^(Expression const& other) const;
             Expression operator&&(Expression const& other) const;
             Expression operator||(Expression const& other) const;
             Expression operator!() const;
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index 739d9ca5b..381ca3e1b 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -47,7 +47,7 @@ TEST(PrismParser, SimpleFullTest) {
     R"(dtmc
     module mod1
         b : bool;
-        [a] true -> 1: (b'=true);
+        [a] true -> 1: (b'=true ^ false <=> b => false);
     endmodule)";
     
     storm::prism::Program result;
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 0c19c5bfb..6ce9f50c5 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -264,6 +264,12 @@ TEST(Expression, OperatorTest) {
     ASSERT_NO_THROW(tempExpression = boolVarExpression.iff(boolConstExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
+    ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = trueExpression ^ falseExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression ^ boolConstExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
+    
     ASSERT_THROW(tempExpression = trueExpression.floor(), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression.floor());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);

From d57a0c9901ca75d287ac68d3662badc777ae5c9f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 17 Apr 2014 18:41:36 +0200
Subject: [PATCH 084/147] Replaced memcpy by std::copy.

Former-commit-id: ef31cf99772064aa660ee1acfc7ab05037b8087a
---
 src/storage/dd/CuddDd.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index c5fb92bbd..7ea5ab260 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -388,14 +388,14 @@ namespace storm {
                 std::vector<char*> ddNames;
                 std::string ddName("f");
                 ddNames.push_back(new char[ddName.size() + 1]);
-                memcpy(ddNames.back(), ddName.c_str(), 2);
+                std::copy(ddName.c_str(), ddName.c_str() + 2, ddNames.back());
                 
                 // Now build the variables names.
                 std::vector<std::string> ddVariableNamesAsStrings = this->getDdManager()->getDdVariableNames();
                 std::vector<char*> ddVariableNames;
                 for (auto const& element : ddVariableNamesAsStrings) {
                     ddVariableNames.push_back(new char[element.size() + 1]);
-                    memcpy(ddVariableNames.back(), element.c_str(), element.size() + 1);
+                    std::copy(element.c_str(), element.c_str() + element.size() + 1, ddVariableNames.back());
                 }
                 
                 // Open the file, dump the DD and close it again.

From 1d8ae9fc899da8a46788dad1abfbc0f0b1006dcb Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Thu, 17 Apr 2014 19:11:52 +0200
Subject: [PATCH 085/147] Fixed an issue with templated variadic template
 arguments (see
 http://stackoverflow.com/questions/23119273/use-a-templated-variadic-template-parameter-as-specialized-parameter
 for discussion)

Former-commit-id: e7d2d054b6115ba4e15a667bba293effd53d470b
---
 src/parser/PrismParser.cpp                    | 12 +++---
 src/storage/expressions/Expression.cpp        | 23 ++++++------
 src/storage/expressions/Expression.h          | 28 ++++++++++++--
 .../IdentifierSubstitutionVisitor.cpp         | 37 ++++++++++---------
 .../IdentifierSubstitutionVisitor.h           |  6 +--
 .../expressions/SubstitutionVisitor.cpp       | 37 ++++++++++---------
 src/storage/expressions/SubstitutionVisitor.h |  6 +--
 src/storage/prism/Assignment.cpp              |  2 +-
 src/storage/prism/BooleanVariable.cpp         |  2 +-
 src/storage/prism/Command.cpp                 |  2 +-
 src/storage/prism/Constant.cpp                |  2 +-
 src/storage/prism/Formula.cpp                 |  2 +-
 src/storage/prism/IntegerVariable.cpp         |  2 +-
 src/storage/prism/Label.cpp                   |  2 +-
 src/storage/prism/Program.cpp                 |  4 +-
 src/storage/prism/StateReward.cpp             |  2 +-
 src/storage/prism/TransitionReward.cpp        |  2 +-
 src/storage/prism/Update.cpp                  |  2 +-
 src/storage/prism/Variable.cpp                |  2 +-
 test/functional/storage/ExpressionTest.cpp    |  2 +-
 20 files changed, 100 insertions(+), 77 deletions(-)

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 6039c2c11..9679168b6 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -585,7 +585,7 @@ namespace storm {
                     auto const& renamingPair = renaming.find(variable.getName());
                     LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
                     
-                    booleanVariables.push_back(storm::prism::BooleanVariable(renamingPair->second, variable.getInitialValueExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1)));
+                    booleanVariables.push_back(storm::prism::BooleanVariable(renamingPair->second, variable.getInitialValueExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1)));
                 }
                 
                 // Rename the integer variables.
@@ -594,7 +594,7 @@ namespace storm {
                     auto const& renamingPair = renaming.find(variable.getName());
                     LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
                     
-                    integerVariables.push_back(storm::prism::IntegerVariable(renamingPair->second, variable.getLowerBoundExpression().substitute<std::map>(expressionRenaming), variable.getUpperBoundExpression().substitute<std::map>(expressionRenaming), variable.getInitialValueExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1)));
+                    integerVariables.push_back(storm::prism::IntegerVariable(renamingPair->second, variable.getLowerBoundExpression().substitute(expressionRenaming), variable.getUpperBoundExpression().substitute(expressionRenaming), variable.getInitialValueExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1)));
                 }
                 
                 // Rename commands.
@@ -606,12 +606,12 @@ namespace storm {
                         for (auto const& assignment : update.getAssignments()) {
                             auto const& renamingPair = renaming.find(assignment.getVariableName());
                             if (renamingPair != renaming.end()) {
-                                assignments.emplace_back(renamingPair->second, assignment.getExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1));
+                                assignments.emplace_back(renamingPair->second, assignment.getExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1));
                             } else {
-                                assignments.emplace_back(assignment.getVariableName(), assignment.getExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1));
+                                assignments.emplace_back(assignment.getVariableName(), assignment.getExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1));
                             }
                         }
-                        updates.emplace_back(globalProgramInformation.currentUpdateIndex, update.getLikelihoodExpression().substitute<std::map>(expressionRenaming), assignments, this->getFilename(), get_line(qi::_1));
+                        updates.emplace_back(globalProgramInformation.currentUpdateIndex, update.getLikelihoodExpression().substitute(expressionRenaming), assignments, this->getFilename(), get_line(qi::_1));
                         ++globalProgramInformation.currentUpdateIndex;
                     }
                     
@@ -621,7 +621,7 @@ namespace storm {
                         newActionName = renamingPair->second;
                     }
                     
-                    commands.emplace_back(globalProgramInformation.currentCommandIndex, newActionName, command.getGuardExpression().substitute<std::map>(expressionRenaming), updates, this->getFilename(), get_line(qi::_1));
+                    commands.emplace_back(globalProgramInformation.currentCommandIndex, newActionName, command.getGuardExpression().substitute(expressionRenaming), updates, this->getFilename(), get_line(qi::_1));
                     ++globalProgramInformation.currentCommandIndex;
                 }
                 
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 7eb94966b..93e356009 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -27,15 +27,21 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        template<template<typename... Arguments> class MapType>
-        Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const {
-            return SubstitutionVisitor<MapType>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
+		Expression Expression::substitute(std::map<std::string, Expression> const& identifierToExpressionMap) const {
+            return SubstitutionVisitor< std::map<std::string, Expression> >(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
         }
+
+		Expression Expression::substitute(std::unordered_map<std::string, Expression> const& identifierToExpressionMap) const {
+			return SubstitutionVisitor< std::unordered_map<std::string, Expression> >(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
+		}
         
-        template<template<typename... Arguments> class MapType>
-        Expression Expression::substitute(MapType<std::string, std::string> const& identifierToIdentifierMap) const {
-            return IdentifierSubstitutionVisitor<MapType>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+		Expression Expression::substitute(std::map<std::string, std::string> const& identifierToIdentifierMap) const {
+			return IdentifierSubstitutionVisitor< std::map<std::string, std::string> >(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
         }
+
+		Expression Expression::substitute(std::unordered_map<std::string, std::string> const& identifierToIdentifierMap) const {
+			return IdentifierSubstitutionVisitor< std::unordered_map<std::string, std::string> >(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+		}
         
         bool Expression::evaluateAsBool(Valuation const* valuation) const {
             return this->getBaseExpression().evaluateAsBool(valuation);
@@ -247,11 +253,6 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(ExpressionReturnType::Int, this->getBaseExpressionPointer(), UnaryNumericalFunctionExpression::OperatorType::Ceil)));
         }
         
-        template Expression Expression::substitute<std::map>(std::map<std::string, storm::expressions::Expression> const&) const;
-        template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, storm::expressions::Expression> const&) const;
-        template Expression Expression::substitute<std::map>(std::map<std::string, std::string> const&) const;
-        template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, std::string> const&) const;
-        
         std::ostream& operator<<(std::ostream& stream, Expression const& expression) {
             stream << expression.getBaseExpression();
             return stream;
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index ea7d99572..3001def0a 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -2,6 +2,8 @@
 #define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 
 #include <memory>
+#include <map>
+#include <unordered_map>
 
 #include "src/storage/expressions/BaseExpression.h"
 #include "src/utility/OsDetection.h"
@@ -76,8 +78,18 @@ namespace storm {
              * @return An expression in which all identifiers in the key set of the mapping are replaced by the
              * expression they are mapped to.
              */
-            template<template<typename... Arguments> class MapType>
-            Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const;
+			Expression substitute(std::map<std::string, Expression> const& identifierToExpressionMap) const;
+
+			/*!
+			* Substitutes all occurrences of identifiers according to the given map. Note that this substitution is
+			* done simultaneously, i.e., identifiers appearing in the expressions that were "plugged in" are not
+			* substituted.
+			*
+			* @param identifierToExpressionMap A mapping from identifiers to the expression they are substituted with.
+			* @return An expression in which all identifiers in the key set of the mapping are replaced by the
+			* expression they are mapped to.
+			*/
+			Expression substitute(std::unordered_map<std::string, Expression> const& identifierToExpressionMap) const;
             
             /*!
              * Substitutes all occurrences of identifiers with different names given by a mapping.
@@ -86,8 +98,16 @@ namespace storm {
              * @return An expression in which all identifiers in the key set of the mapping are replaced by the
              * identifiers they are mapped to.
              */
-            template<template<typename... Arguments> class MapType>
-            Expression substitute(MapType<std::string, std::string> const& identifierToIdentifierMap) const;
+			Expression substitute(std::map<std::string, std::string> const& identifierToIdentifierMap) const;
+
+			/*!
+			* Substitutes all occurrences of identifiers with different names given by a mapping.
+			*
+			* @param identifierToIdentifierMap A mapping from identifiers to identifiers they are substituted with.
+			* @return An expression in which all identifiers in the key set of the mapping are replaced by the
+			* identifiers they are mapped to.
+			*/
+			Expression substitute(std::unordered_map<std::string, std::string> const& identifierToIdentifierMap) const;
             
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
index 17161775a..1b058bed2 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
@@ -1,5 +1,6 @@
 #include <map>
 #include <unordered_map>
+#include <string>
 
 #include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
 
@@ -19,18 +20,18 @@
 
 namespace storm {
     namespace expressions  {
-        template<template<typename... Arguments> class MapType>
-        IdentifierSubstitutionVisitor<MapType>::IdentifierSubstitutionVisitor(MapType<std::string, std::string> const& identifierToIdentifierMap) : identifierToIdentifierMap(identifierToIdentifierMap) {
+		template<typename MapType>
+        IdentifierSubstitutionVisitor<MapType>::IdentifierSubstitutionVisitor(MapType const& identifierToIdentifierMap) : identifierToIdentifierMap(identifierToIdentifierMap) {
             // Intentionally left empty.
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         Expression IdentifierSubstitutionVisitor<MapType>::substitute(BaseExpression const* expression) {
             expression->accept(this);
             return Expression(this->expressionStack.top());
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(IfThenElseExpression const* expression) {
             expression->getCondition()->accept(this);
             std::shared_ptr<BaseExpression const> conditionExpression = expressionStack.top();
@@ -52,7 +53,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
             expression->getFirstOperand()->accept(this);
             std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
@@ -70,7 +71,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(BinaryNumericalFunctionExpression const* expression) {
             expression->getFirstOperand()->accept(this);
             std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
@@ -88,7 +89,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(BinaryRelationExpression const* expression) {
             expression->getFirstOperand()->accept(this);
             std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
@@ -106,7 +107,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
             // If the boolean constant is in the key set of the substitution, we need to replace it.
             auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
@@ -117,7 +118,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
             // If the double constant is in the key set of the substitution, we need to replace it.
             auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
@@ -128,7 +129,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
             // If the integer constant is in the key set of the substitution, we need to replace it.
             auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
@@ -139,7 +140,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(VariableExpression const* expression) {
             // If the variable is in the key set of the substitution, we need to replace it.
             auto const& namePair = this->identifierToIdentifierMap.find(expression->getVariableName());
@@ -150,7 +151,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(UnaryBooleanFunctionExpression const* expression) {
             expression->getOperand()->accept(this);
             std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
@@ -164,7 +165,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(UnaryNumericalFunctionExpression const* expression) {
             expression->getOperand()->accept(this);
             std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
@@ -178,23 +179,23 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(BooleanLiteralExpression const* expression) {
             this->expressionStack.push(expression->getSharedPointer());
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(IntegerLiteralExpression const* expression) {
             this->expressionStack.push(expression->getSharedPointer());
         }
         
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(DoubleLiteralExpression const* expression) {
             this->expressionStack.push(expression->getSharedPointer());
         }
         
         // Explicitly instantiate the class with map and unordered_map.
-        template class IdentifierSubstitutionVisitor<std::map>;
-        template class IdentifierSubstitutionVisitor<std::unordered_map>;
+		template class IdentifierSubstitutionVisitor< std::map<std::string, std::string> >;
+		template class IdentifierSubstitutionVisitor< std::unordered_map<std::string, std::string> >;
     }
 }
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.h b/src/storage/expressions/IdentifierSubstitutionVisitor.h
index 6be7aa9ca..e8412d949 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.h
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.h
@@ -8,7 +8,7 @@
 
 namespace storm {
     namespace expressions {
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         class IdentifierSubstitutionVisitor : public ExpressionVisitor {
         public:
             /*!
@@ -16,7 +16,7 @@ namespace storm {
              *
              * @param identifierToExpressionMap A mapping from identifiers to expressions.
              */
-            IdentifierSubstitutionVisitor(MapType<std::string, std::string> const& identifierToExpressionMap);
+            IdentifierSubstitutionVisitor(MapType const& identifierToExpressionMap);
             
             /*!
              * Substitutes the identifiers in the given expression according to the previously given map and returns the
@@ -47,7 +47,7 @@ namespace storm {
             std::stack<std::shared_ptr<BaseExpression const>> expressionStack;
             
             // A mapping of identifier names to expressions with which they shall be replaced.
-            MapType<std::string, std::string> const& identifierToIdentifierMap;
+            MapType const& identifierToIdentifierMap;
         };
     }
 }
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index c3f2ea0a8..54b533d49 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -1,5 +1,6 @@
 #include <map>
 #include <unordered_map>
+#include <string>
 
 #include "src/storage/expressions/SubstitutionVisitor.h"
 
@@ -19,18 +20,18 @@
 
 namespace storm {
     namespace expressions  {
-        template<template<typename... Arguments> class MapType>
-        SubstitutionVisitor<MapType>::SubstitutionVisitor(MapType<std::string, Expression> const& identifierToExpressionMap) : identifierToExpressionMap(identifierToExpressionMap) {
+        template<typename MapType>
+        SubstitutionVisitor<MapType>::SubstitutionVisitor(MapType const& identifierToExpressionMap) : identifierToExpressionMap(identifierToExpressionMap) {
             // Intentionally left empty.
         }
 
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         Expression SubstitutionVisitor<MapType>::substitute(BaseExpression const* expression) {
             expression->accept(this);
             return Expression(this->expressionStack.top());
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(IfThenElseExpression const* expression) {
             expression->getCondition()->accept(this);
             std::shared_ptr<BaseExpression const> conditionExpression = expressionStack.top();
@@ -52,7 +53,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
             expression->getFirstOperand()->accept(this);
             std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
@@ -70,7 +71,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(BinaryNumericalFunctionExpression const* expression) {
             expression->getFirstOperand()->accept(this);
             std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
@@ -88,7 +89,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(BinaryRelationExpression const* expression) {
             expression->getFirstOperand()->accept(this);
             std::shared_ptr<BaseExpression const> firstExpression = expressionStack.top();
@@ -106,7 +107,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
             // If the boolean constant is in the key set of the substitution, we need to replace it.
             auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
@@ -117,7 +118,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
             // If the double constant is in the key set of the substitution, we need to replace it.
             auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
@@ -128,7 +129,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
             // If the integer constant is in the key set of the substitution, we need to replace it.
             auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
@@ -139,7 +140,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(VariableExpression const* expression) {
             // If the variable is in the key set of the substitution, we need to replace it.
             auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getVariableName());
@@ -150,7 +151,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(UnaryBooleanFunctionExpression const* expression) {
             expression->getOperand()->accept(this);
             std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
@@ -164,7 +165,7 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(UnaryNumericalFunctionExpression const* expression) {
             expression->getOperand()->accept(this);
             std::shared_ptr<BaseExpression const> operandExpression = expressionStack.top();
@@ -178,23 +179,23 @@ namespace storm {
             }
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(BooleanLiteralExpression const* expression) {
             this->expressionStack.push(expression->getSharedPointer());
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(IntegerLiteralExpression const* expression) {
             this->expressionStack.push(expression->getSharedPointer());
         }
         
-        template<template<typename... Arguments> class MapType>
+		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(DoubleLiteralExpression const* expression) {
             this->expressionStack.push(expression->getSharedPointer());
         }
         
         // Explicitly instantiate the class with map and unordered_map.
-        template class SubstitutionVisitor<std::map>;
-        template class SubstitutionVisitor<std::unordered_map>;
+		template class SubstitutionVisitor< std::map<std::string, Expression> >;
+		template class SubstitutionVisitor< std::unordered_map<std::string, Expression> >;
     }
 }
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index ad29ad6ab..d46d62cee 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -8,7 +8,7 @@
 
 namespace storm {
     namespace expressions {
-        template<template<typename... Arguments> class MapType>
+        template<typename MapType>
         class SubstitutionVisitor : public ExpressionVisitor {
         public:
             /*!
@@ -16,7 +16,7 @@ namespace storm {
              *
              * @param identifierToExpressionMap A mapping from identifiers to expressions.
              */
-            SubstitutionVisitor(MapType<std::string, Expression> const& identifierToExpressionMap);
+            SubstitutionVisitor(MapType const& identifierToExpressionMap);
             
             /*!
              * Substitutes the identifiers in the given expression according to the previously given map and returns the
@@ -47,7 +47,7 @@ namespace storm {
             std::stack<std::shared_ptr<BaseExpression const>> expressionStack;
             
             // A mapping of identifier names to expressions with which they shall be replaced.
-            MapType<std::string, Expression> const& identifierToExpressionMap;
+            MapType const& identifierToExpressionMap;
         };
     }
 }
diff --git a/src/storage/prism/Assignment.cpp b/src/storage/prism/Assignment.cpp
index f15797e6d..3b63703ed 100644
--- a/src/storage/prism/Assignment.cpp
+++ b/src/storage/prism/Assignment.cpp
@@ -15,7 +15,7 @@ namespace storm {
         }
         
         Assignment Assignment::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Assignment(this->getVariableName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Assignment(this->getVariableName(), this->getExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Assignment const& assignment) {
diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
index 478b9322d..ef88cefc4 100644
--- a/src/storage/prism/BooleanVariable.cpp
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -11,7 +11,7 @@ namespace storm {
         }
         
         BooleanVariable BooleanVariable::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return BooleanVariable(this->getName(), this->getInitialValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return BooleanVariable(this->getName(), this->getInitialValueExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable) {
diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index f075ff6c6..4b36942df 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -37,7 +37,7 @@ namespace storm {
                 newUpdates.emplace_back(update.substitute(substitution));
             }
             
-            return Command(this->getGlobalIndex(), this->getActionName(), this->getGuardExpression().substitute<std::map>(substitution), newUpdates, this->getFilename(), this->getLineNumber());
+            return Command(this->getGlobalIndex(), this->getActionName(), this->getGuardExpression().substitute(substitution), newUpdates, this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Command const& command) {
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 160e9ad22..3df0a26bc 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -27,7 +27,7 @@ namespace storm {
         }
         
         Constant Constant::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Constant(this->getType(), this->getName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Constant(this->getType(), this->getName(), this->getExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Constant const& constant) {
diff --git a/src/storage/prism/Formula.cpp b/src/storage/prism/Formula.cpp
index 3bf72a7de..fbda0c69d 100644
--- a/src/storage/prism/Formula.cpp
+++ b/src/storage/prism/Formula.cpp
@@ -19,7 +19,7 @@ namespace storm {
         }
         
         Formula Formula::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Formula(this->getName(), this->getExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Formula(this->getName(), this->getExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Formula const& formula) {
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index a80b6394e..1968a07ca 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -19,7 +19,7 @@ namespace storm {
         }
         
         IntegerVariable IntegerVariable::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return IntegerVariable(this->getName(), this->getLowerBoundExpression().substitute<std::map>(substitution), this->getUpperBoundExpression().substitute<std::map>(substitution), this->getInitialValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return IntegerVariable(this->getName(), this->getLowerBoundExpression().substitute(substitution), this->getUpperBoundExpression().substitute(substitution), this->getInitialValueExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable) {
diff --git a/src/storage/prism/Label.cpp b/src/storage/prism/Label.cpp
index a78f9079f..cb8a13f25 100644
--- a/src/storage/prism/Label.cpp
+++ b/src/storage/prism/Label.cpp
@@ -15,7 +15,7 @@ namespace storm {
         }
         
         Label Label::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return Label(this->getName(), this->getStatePredicateExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return Label(this->getName(), this->getStatePredicateExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Label const& label) {
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index cdbba3e22..1c4118b8b 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -229,7 +229,7 @@ namespace storm {
                     LOG_THROW(constantDefinitions.find(constant.getName()) == constantDefinitions.end(), storm::exceptions::InvalidArgumentException, "Illegally defining already defined constant '" << constant.getName() << "'.");
                     
                     // Now replace the occurrences of undefined constants in its defining expression.
-                    newConstants.emplace_back(constant.getType(), constant.getName(), constant.getExpression().substitute<std::map>(constantDefinitions), constant.getFilename(), constant.getLineNumber());
+                    newConstants.emplace_back(constant.getType(), constant.getName(), constant.getExpression().substitute(constantDefinitions), constant.getFilename(), constant.getLineNumber());
                 } else {
                     auto const& variableExpressionPair = constantDefinitions.find(constant.getName());
                     
@@ -306,7 +306,7 @@ namespace storm {
                 newRewardModels.emplace_back(rewardModel.substitute(constantSubstitution));
             }
             
-            storm::expressions::Expression newInitialStateExpression = this->getInitialStatesExpression().substitute<std::map>(constantSubstitution);
+            storm::expressions::Expression newInitialStateExpression = this->getInitialStatesExpression().substitute(constantSubstitution);
             
             std::vector<Label> newLabels;
             newLabels.reserve(this->getNumberOfLabels());
diff --git a/src/storage/prism/StateReward.cpp b/src/storage/prism/StateReward.cpp
index ab2f0974b..a93729b52 100644
--- a/src/storage/prism/StateReward.cpp
+++ b/src/storage/prism/StateReward.cpp
@@ -15,7 +15,7 @@ namespace storm {
         }
         
         StateReward StateReward::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return StateReward(this->getStatePredicateExpression().substitute<std::map>(substitution), this->getRewardValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return StateReward(this->getStatePredicateExpression().substitute(substitution), this->getRewardValueExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, StateReward const& stateReward) {
diff --git a/src/storage/prism/TransitionReward.cpp b/src/storage/prism/TransitionReward.cpp
index 0034231d8..cef7bf654 100644
--- a/src/storage/prism/TransitionReward.cpp
+++ b/src/storage/prism/TransitionReward.cpp
@@ -19,7 +19,7 @@ namespace storm {
         }
         
         TransitionReward TransitionReward::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
-            return TransitionReward(this->getActionName(), this->getStatePredicateExpression().substitute<std::map>(substitution), this->getRewardValueExpression().substitute<std::map>(substitution), this->getFilename(), this->getLineNumber());
+            return TransitionReward(this->getActionName(), this->getStatePredicateExpression().substitute(substitution), this->getRewardValueExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, TransitionReward const& transitionReward) {
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index 2e01187c9..5d65e6dd5 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -44,7 +44,7 @@ namespace storm {
                 newAssignments.emplace_back(assignment.substitute(substitution));
             }
             
-            return Update(this->getGlobalIndex(), this->getLikelihoodExpression().substitute<std::map>(substitution), newAssignments, this->getFilename(), this->getLineNumber());
+            return Update(this->getGlobalIndex(), this->getLikelihoodExpression().substitute(substitution), newAssignments, this->getFilename(), this->getLineNumber());
         }
         
         std::ostream& operator<<(std::ostream& stream, Update const& update) {
diff --git a/src/storage/prism/Variable.cpp b/src/storage/prism/Variable.cpp
index e6c884813..4aabd548c 100644
--- a/src/storage/prism/Variable.cpp
+++ b/src/storage/prism/Variable.cpp
@@ -8,7 +8,7 @@ namespace storm {
             // Nothing to do here.
         }
         
-        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), name(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute<std::map>(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
+        Variable::Variable(Variable const& oldVariable, std::string const& newName, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), name(newName), initialValueExpression(oldVariable.getInitialValueExpression().substitute(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
             // Intentionally left empty.
         }
         
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 41556f6d6..d70cbd7d1 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -306,7 +306,7 @@ TEST(Expression, SubstitutionTest) {
 
     std::map<std::string, storm::expressions::Expression> substution = { std::make_pair("y", doubleConstExpression), std::make_pair("x", storm::expressions::Expression::createTrue()), std::make_pair("a", storm::expressions::Expression::createTrue()) };
     storm::expressions::Expression substitutedExpression;
-    ASSERT_NO_THROW(substitutedExpression = tempExpression.substitute<std::map>(substution));
+    ASSERT_NO_THROW(substitutedExpression = tempExpression.substitute(substution));
     EXPECT_TRUE(substitutedExpression.simplify().isTrue());
 }
 

From 0a501b6e76208c82c177b2296718873a97e3d10c Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Fri, 18 Apr 2014 13:48:17 +0200
Subject: [PATCH 086/147] Added a constructor for GlobalProgramInformation as
 MSVC fails to default bool to false.

Former-commit-id: bd50a770c8341b19d60549545775d96dd13d1795
---
 src/parser/PrismParser.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 98053890a..15acef30b 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -33,7 +33,7 @@ namespace storm {
         class GlobalProgramInformation {
         public:
             // Default construct the header information.
-            GlobalProgramInformation() = default;
+			GlobalProgramInformation() : hasInitialStatesExpression(false), currentCommandIndex(0), currentUpdateIndex(0) {}
             
             // Members for all essential information that needs to be collected.
             storm::prism::Program::ModelType modelType;

From f2383ccfb563ac4cc6a84c3a258e0c6adfea8033 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Fri, 18 Apr 2014 21:16:02 +0200
Subject: [PATCH 087/147] Added missing definitions required for CUDD to
 compile under 64bit architectures.

Former-commit-id: 4e40ea7ee36e6732b2a5218e73a910de217d1671
---
 resources/3rdparty/cudd-2.5.0/CMakeLists.txt | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/resources/3rdparty/cudd-2.5.0/CMakeLists.txt b/resources/3rdparty/cudd-2.5.0/CMakeLists.txt
index c7cff2aca..4d08513de 100644
--- a/resources/3rdparty/cudd-2.5.0/CMakeLists.txt
+++ b/resources/3rdparty/cudd-2.5.0/CMakeLists.txt
@@ -25,5 +25,14 @@ if(MSVC)
 	add_definitions(/D_SCL_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS)
 endif()
 
+# Since we do not target Alphas, this symbol is always set
+add_definitions(-DHAVE_IEEE_754)
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+	message(STATUS "CUDD: Targeting 64bit architecture")
+	add_definitions(-DSIZEOF_VOID_P=8)
+	add_definitions(-DSIZEOF_LONG=8)
+endif()
+
 # Add the library
 add_library(cudd ${CUDD_SOURCES} ${CUDD_HEADERS} ${CUDD_HEADERS_CXX} ${CUDD_SOURCES_CXX})
\ No newline at end of file

From 6078e074761df613a1890ddf8bf531690038ab25 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 18 Apr 2014 22:07:54 +0200
Subject: [PATCH 088/147] First version of DD iterator; small test included.

Former-commit-id: 2ec2323886ac67717bb9864a9d2f2c0cbb1d98ae
---
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.cc    |   2 +-
 .../3rdparty/cudd-2.5.0/src/obj/cuddObj.hh    |   2 +-
 src/storage/dd/CuddDd.cpp                     |  11 ++
 src/storage/dd/CuddDd.h                       |  16 ++
 src/storage/dd/CuddDdForwardIterator.cpp      | 148 ++++++++++++++++--
 src/storage/dd/CuddDdForwardIterator.h        | 102 ++++++++++--
 src/storage/dd/CuddDdManager.cpp              |  12 ++
 src/storage/dd/CuddDdManager.h                |  14 +-
 src/storage/dd/DdMetaVariable.cpp             |  15 +-
 src/storage/dd/DdMetaVariable.h               |  25 ++-
 src/storage/expressions/SimpleValuation.cpp   |  11 +-
 test/functional/storage/CuddDdTest.cpp        |  21 +++
 12 files changed, 350 insertions(+), 29 deletions(-)

diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
index d62328ff0..fcec76782 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
@@ -5280,7 +5280,7 @@ int
 ABDD::NextCube(
   DdGen * gen,
   int ** cube,
-  CUDD_VALUE_TYPE * value) const
+  CUDD_VALUE_TYPE * value) 
 {
     return Cudd_NextCube(gen, cube, value);
 
diff --git a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
index d8c2d0722..1162a968c 100644
--- a/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
+++ b/resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
@@ -192,7 +192,7 @@ public:
 	const;
     int CountLeaves() const;
     DdGen * FirstCube(int ** cube, CUDD_VALUE_TYPE * value) const;
-    int NextCube(DdGen * gen, int ** cube, CUDD_VALUE_TYPE * value) const;
+    static int NextCube(DdGen * gen, int ** cube, CUDD_VALUE_TYPE * value);
     double Density(int nvars) const;
 
 }; // ABDD
diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 313a2b4d8..d07696d08 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -434,6 +434,17 @@ namespace storm {
             return this->ddManager;
         }
         
+        DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::begin() const {
+            int* cube;
+            double value;
+            DdGen* generator = this->getCuddAdd().FirstCube(&cube, &value);
+            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, Cudd_IsGenEmpty(generator), &this->getContainedMetaVariableNames());
+        }
+        
+        DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::end() const {
+            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), nullptr, nullptr, 0, true, nullptr);
+        }
+        
         std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
             dd.exportToDot();
             return out;
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index fa780f263..33318ed38 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -7,6 +7,7 @@
 #include <iostream>
 
 #include "src/storage/dd/Dd.h"
+#include "src/storage/dd/CuddDdForwardIterator.h"
 #include "src/utility/OsDetection.h"
 
 // Include the C++-interface of CUDD.
@@ -22,6 +23,7 @@ namespace storm {
         public:
             // Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
             friend class DdManager<DdType::CUDD>;
+            friend class DdForwardIterator<DdType::CUDD>;
             
             // Instantiate all copy/move constructors/assignments with the default implementation.
             Dd() = default;
@@ -405,6 +407,20 @@ namespace storm {
              */
             std::shared_ptr<DdManager<DdType::CUDD>> getDdManager() const;
             
+            /*!
+             * Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
+             *
+             * @return An iterator that points to the first meta variable assignment with a non-zero function value.
+             */
+            DdForwardIterator<DdType::CUDD> begin() const;
+            
+            /*!
+             * Retrieves an iterator that points past the end of the container.
+             *
+             * @return An iterator that points past the end of the container.
+             */
+            DdForwardIterator<DdType::CUDD> end() const;
+            
             friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
         private:
             /*!
diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp
index fc66895dd..c0e754c8b 100644
--- a/src/storage/dd/CuddDdForwardIterator.cpp
+++ b/src/storage/dd/CuddDdForwardIterator.cpp
@@ -1,24 +1,152 @@
 #include "src/storage/dd/CuddDdForwardIterator.h"
+#include "src/storage/dd/CuddDdManager.h"
+#include "src/storage/dd/DdMetaVariable.h"
+#include "src/exceptions/ExceptionMacros.h"
 
 namespace storm {
     namespace dd {
-        DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd) : ddManager(ddManager), value(0), cube(nullptr), cuddAdd(cuddAdd), isAtEnd(false), generator(nullptr) {
-            // Start by getting the first cube.
-            this->generator = this->cuddAdd.FirstCube(&cube, &value);
-            
-            // If the generator is already empty, we set the corresponding flag.
-            this->isAtEnd = Cudd_IsGenEmpty(generator);
+        DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<std::string> const* metaVariables) : ddManager(ddManager), generator(generator), cube(cube), value(value), isAtEnd(isAtEnd), metaVariables(metaVariables), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
+            // 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) {
+                // Start by registering all meta variables in the valuation with the appropriate type.
+                for (auto const& metaVariableName : *this->metaVariables) {
+                    auto const& metaVariable = this->ddManager->getMetaVariable(metaVariableName);
+                    switch (metaVariable.getType()) {
+                        case DdMetaVariable<DdType::CUDD>::MetaVariableType::Bool: currentValuation.addBooleanIdentifier(metaVariableName); break;
+                        case DdMetaVariable<DdType::CUDD>::MetaVariableType::Int: currentValuation.addIntegerIdentifier(metaVariableName); break;
+                    }
+                }
+
+                // And then get ready for treating the first cube.
+                this->treatNewCube();
+            }
+        }
+        
+        DdForwardIterator<DdType::CUDD>::DdForwardIterator(DdForwardIterator<DdType::CUDD>&& other) : ddManager(other.ddManager), generator(other.generator), cube(other.cube), value(other.value), isAtEnd(other.isAtEnd), metaVariables(other.metaVariables), cubeCounter(other.cubeCounter), relevantDontCareDdVariables(other.relevantDontCareDdVariables), currentValuation(other.currentValuation) {
+            // Null-out the pointers of which we took possession.
+            other.cube = nullptr;
+            other.generator = nullptr;
+        }
+        
+        DdForwardIterator<DdType::CUDD>& DdForwardIterator<DdType::CUDD>::operator=(DdForwardIterator<DdType::CUDD>&& other) {
+            if (this != &other) {
+                this->ddManager = other.ddManager;
+                this->generator = other.generator;
+                this->cube = other.cube;
+                this->value = other.value;
+                this->isAtEnd = other.isAtEnd;
+                this->metaVariables = other.metaVariables;
+                this->cubeCounter = other.cubeCounter;
+                this->relevantDontCareDdVariables = other.relevantDontCareDdVariables;
+                this->currentValuation = other.currentValuation;
+                
+                // Null-out the pointers of which we took possession.
+                other.cube = nullptr;
+                other.generator = nullptr;
+            }
+            return *this;
+        }
+        
+        DdForwardIterator<DdType::CUDD>::~DdForwardIterator() {
+            if (this->cube != nullptr) {
+                free(this->cube);
+            }
+            if (this->generator != nullptr) {
+                free(this->generator);
+            }
         }
         
         DdForwardIterator<DdType::CUDD>& DdForwardIterator<DdType::CUDD>::operator++() {
-            // TODO: eliminate current
+            LOG_ASSERT(!this->isAtEnd, "Illegally incrementing iterator that is already at its end.");
+            
+            // If there were no (relevant) don't cares or we have enumerated all combination, we need to eliminate the
+            // found solutions and get the next "first" cube.
+            if (this->relevantDontCareDdVariables.empty() || this->cubeCounter >= std::pow(2, this->relevantDontCareDdVariables.size()) - 1) {
+                // Get the next cube and check for emptiness.
+                ABDD::NextCube(generator, &cube, &value);
+                this->isAtEnd = Cudd_IsGenEmpty(generator);
+
+                // In case we are not done yet, we get ready to treat the next cube.
+                if (!this->isAtEnd) {
+                    this->treatNewCube();
+                }
+            } else {
+                // Treat the next solution of the cube.
+                this->treatNextInCube();
+            }
+            
+            return *this;
+        }
+        
+        void DdForwardIterator<DdType::CUDD>::treatNextInCube() {
+            // Start by increasing the counter and check which bits we need to set/unset in the new valuation.
+            ++this->cubeCounter;
+            
+            for (uint_fast64_t index = 0; index < this->relevantDontCareDdVariables.size(); ++index) {
+                auto const& metaVariable = this->ddManager->getMetaVariable(std::get<1>(this->relevantDontCareDdVariables[index]));
+                if (metaVariable.getType() == DdMetaVariable<DdType::CUDD>::MetaVariableType::Bool) {
+                    if ((this->cubeCounter & (1ull << index)) != 0) {
+                        currentValuation.setBooleanValue(metaVariable.getName(), true);
+                    } else {
+                        currentValuation.setBooleanValue(metaVariable.getName(), false);
+                    }
+                } else {
+                    if ((this->cubeCounter & (1ull << index)) != 0) {
+                        currentValuation.setIntegerValue(metaVariable.getName(), ((currentValuation.getIntegerValue(metaVariable.getName()) - metaVariable.getLow()) | (1ull << std::get<2>(this->relevantDontCareDdVariables[index]))) + metaVariable.getLow());
+                    } else {
+                        currentValuation.setIntegerValue(metaVariable.getName(), ((currentValuation.getIntegerValue(metaVariable.getName()) - metaVariable.getLow()) & ~(1ull << std::get<2>(this->relevantDontCareDdVariables[index]))) + metaVariable.getLow());
+                    }
+                }
+            }
+        }
+        
+        void DdForwardIterator<DdType::CUDD>::treatNewCube() {
+            this->relevantDontCareDdVariables.clear();
+            
+            // Now loop through the bits of all meta variables and check whether they need to be set, not set or are
+            // don't cares. In the latter case, we add them to a special list, so we can iterate over their concrete
+            // valuations later.
+            for (auto const& metaVariableName : *this->metaVariables) {
+                auto const& metaVariable = this->ddManager->getMetaVariable(metaVariableName);
+                if (metaVariable.getType() == DdMetaVariable<DdType::CUDD>::MetaVariableType::Bool) {
+                    if (this->cube[metaVariable.getDdVariables()[0].getCuddAdd().NodeReadIndex()] == 0) {
+                        currentValuation.setBooleanValue(metaVariableName, false);
+                    } else if (this->cube[metaVariable.getDdVariables()[0].getCuddAdd().NodeReadIndex()] == 1) {
+                        currentValuation.setBooleanValue(metaVariableName, true);
+                    } else {
+                        relevantDontCareDdVariables.push_back(std::make_tuple(metaVariable.getDdVariables()[0].getCuddAdd(), metaVariableName, 0));
+                    }
+                } else {
+                    int_fast64_t intValue = 0;
+                    for (uint_fast64_t bitIndex = 0; bitIndex < metaVariable.getNumberOfDdVariables(); ++bitIndex) {
+                        if (cube[metaVariable.getDdVariables()[bitIndex].getCuddAdd().NodeReadIndex()] == 0) {
+                            // Leave bit unset.
+                        } else if (cube[metaVariable.getDdVariables()[bitIndex].getCuddAdd().NodeReadIndex()] == 1) {
+                            intValue |= 1ull << (metaVariable.getNumberOfDdVariables() - bitIndex - 1);
+                        } else {
+                            // Temporarily leave bit unset so we can iterate trough the other option later.
+                            // Add the bit to the relevant don't care bits.
+                            this->relevantDontCareDdVariables.push_back(std::make_tuple(metaVariable.getDdVariables()[bitIndex].getCuddAdd(), metaVariableName, metaVariable.getNumberOfDdVariables() - bitIndex - 1));
+                        }
+                    }
+                    currentValuation.setIntegerValue(metaVariableName, intValue + metaVariable.getLow());
+                }
+            }
+            
+            // Finally, reset the cube counter.
+            this->cubeCounter = 0;
         }
         
         bool DdForwardIterator<DdType::CUDD>::operator==(DdForwardIterator<DdType::CUDD> const& other) const {
             if (this->isAtEnd && other.isAtEnd) {
                 return true;
             } else {
-                return this->cuddAdd == other.cuddAdd;
+                return this->ddManager.get() == other.ddManager.get() && this->generator == other.generator
+                && this->cube == other.cube && this->value == other.value && this->isAtEnd == other.isAtEnd
+                && this->metaVariables == other.metaVariables && this->cubeCounter == other.cubeCounter
+                && this->relevantDontCareDdVariables == other.relevantDontCareDdVariables
+                && this->currentValuation == other.currentValuation;
             }
         }
         
@@ -26,8 +154,8 @@ namespace storm {
             return !(*this == other);
         }
         
-        storm::expressions::SimpleValuation DdForwardIterator<DdType::CUDD>::operator*() const {
-            // FIXME: construct valuation and return it.
+        std::pair<storm::expressions::SimpleValuation, double> DdForwardIterator<DdType::CUDD>::operator*() const {
+            return std::make_pair(currentValuation, value);
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdForwardIterator.h b/src/storage/dd/CuddDdForwardIterator.h
index 09c627b14..054438d2e 100644
--- a/src/storage/dd/CuddDdForwardIterator.h
+++ b/src/storage/dd/CuddDdForwardIterator.h
@@ -3,6 +3,9 @@
 
 #include <memory>
 #include <cstdint>
+#include <set>
+#include <tuple>
+#include <utility>
 
 #include "src/storage/dd/DdForwardIterator.h"
 #include "src/storage/expressions/SimpleValuation.h"
@@ -12,33 +15,114 @@
 
 namespace storm {
     namespace dd {
+        // Forward-declare the DdManager class.
+        template<DdType Type> class DdManager;
+        template<DdType Type> class Dd;
+        
         template<>
         class DdForwardIterator<DdType::CUDD> {
         public:
-            // Forward-declare the DdManager class.
-            template<DdType Type> class DdManager;
+            friend class Dd<DdType::CUDD>;
+
+            // Default-instantiate the constructor.
+            DdForwardIterator() = default;
+            
+            // Forbid copy-construction and copy assignment, because ownership of the internal pointer is unclear then.
+            DdForwardIterator(DdForwardIterator<DdType::CUDD> const& other) = delete;
+            DdForwardIterator& operator=(DdForwardIterator<DdType::CUDD> const& other) = delete;
+            
+            // Provide move-construction and move-assignment, though.
+            DdForwardIterator(DdForwardIterator<DdType::CUDD>&& other);
+            DdForwardIterator& operator=(DdForwardIterator<DdType::CUDD>&& other);
             
+            /*!
+             * Destroys the forward iterator and frees the generator as well as the cube if they are not the nullptr.
+             */
+            ~DdForwardIterator();
+            
+            /*!
+             * Moves the iterator one position forward.
+             */
             DdForwardIterator<DdType::CUDD>& operator++();
-            storm::expressions::SimpleValuation operator*() const;
+            
+            /*!
+             * Returns a pair consisting of a valuation of meta variables and the value to which this valuation is
+             * mapped. Note that the result is returned by value.
+             *
+             * @return A pair of a valuation and the function value.
+             */
+            std::pair<storm::expressions::SimpleValuation, double> operator*() const;
+            
+            /*!
+             * Compares the iterator with the given one. Two iterators are considered equal when all their underlying
+             * data members are the same or they both are at their end.
+             *
+             * @param other The iterator with which to compare.
+             * @return True if the two iterators are considered equal.
+             */
             bool operator==(DdForwardIterator<DdType::CUDD> const& other) const;
+            
+            /*!
+             * Compares the iterator with the given one. Two iterators are considered unequal iff they are not
+             * considered equal.
+             *
+             * @param other The iterator with which to compare.
+             * @return True if the two iterators are considered unequal.
+             */
             bool operator!=(DdForwardIterator<DdType::CUDD> const& other) const;
             
         private:
-            DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::vector<ADD> const& relevantDdVariables);
+            /*!
+             * Constructs a forward iterator using the given generator with the given set of relevant meta variables.
+             *
+             * @param ddManager The manager responsible for the DD over which to iterate.
+             * @param generator The generator used to enumerate the cubes of the DD.
+             * @param cube The cube as represented by CUDD.
+             * @param value The value the cube is mapped to.
+             * @param isAtEnd A flag that indicates whether the iterator is at its end and may not be moved forward any
+             * more.
+             * @param metaVariables The meta variables that appear in the DD.
+             */
+            DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<std::string> const* metaVariables = nullptr);
+            
+            /*!
+             * Recreates the internal information when a new cube needs to be treated.
+             */
+            void treatNewCube();
+            
+            /*!
+             * Updates the internal information when the next solution of the current cube needs to be treated.
+             */
+            void treatNextInCube();
             
+            // The manager responsible for the meta variables (and therefore the underlying DD).
             std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
             
-            double value;
+            // The CUDD generator used to enumerate the cubes of the DD.
+            DdGen* generator;
             
+            // The currently considered cube of the DD.
             int* cube;
-            
-            uint_fast64_t positionInCube;
 
-            ADD cuddAdd;
+            // The function value of the current cube.
+            double value;
             
+            // A flag that indicates whether the iterator is at its end and may not be moved further. This is also used
+            // for the check against the end iterator.
             bool isAtEnd;
             
-            DdGen* generator;
+            // The set of meta variables appearing in the DD.
+            std::set<std::string> const* metaVariables;
+            
+            // A number that represents how many assignments of the current cube have already been returned previously.
+            // This is needed, because cubes may represent many assignments (if they have don't care variables).
+            uint_fast64_t cubeCounter;
+            
+            // A vector of tuples of the form <variable, metaVariableName, bitIndex>.
+            std::vector<std::tuple<ADD, std::string, uint_fast64_t>> relevantDontCareDdVariables;
+            
+            // The current valuation of meta variables.
+            storm::expressions::SimpleValuation currentValuation;
         };
     }
 }
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 2d77c6350..c75a7c211 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -111,6 +111,18 @@ namespace storm {
             metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, low, high, variables, this->shared_from_this()));
         }
         
+        void DdManager<DdType::CUDD>::addMetaVariable(std::string const& name) {
+            // Check whether a meta variable already exists.
+            if (this->hasMetaVariable(name)) {
+                throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
+            }
+            
+            std::vector<Dd<DdType::CUDD>> variables;
+            variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
+            
+            metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, variables, this->shared_from_this()));
+        }
+        
         void DdManager<DdType::CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
             // Make sure that at least one meta variable is added.
             if (names.size() == 0) {
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 96daeb34a..6df3dc25c 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -5,7 +5,6 @@
 
 #include "src/storage/dd/DdManager.h"
 #include "src/storage/dd/DdMetaVariable.h"
-#include "src/storage/dd/CuddDd.h"
 #include "src/utility/OsDetection.h"
 
 // Include the C++-interface of CUDD.
@@ -16,7 +15,6 @@ namespace storm {
         template<>
         class DdManager<DdType::CUDD> : public std::enable_shared_from_this<DdManager<DdType::CUDD>> {
         public:
-            // To break the cylic dependencies, we need to forward-declare the other DD-related classes.
             friend class Dd<DdType::CUDD>;
             
             /*!
@@ -83,7 +81,7 @@ namespace storm {
             Dd<DdType::CUDD> getIdentity(std::string const& metaVariableName);
             
             /*!
-             * Adds a meta variable with the given name and range.
+             * Adds an integer meta variable with the given name and range.
              *
              * @param name The name of the meta variable.
              * @param low The lowest value of the range of the variable.
@@ -92,7 +90,15 @@ namespace storm {
             void addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high);
             
             /*!
-             * Adds meta variables with the given names and (equal) range and arranges the DD variables in an interleaved order.
+             * Adds a boolean meta variable with the given name.
+             *
+             * @param name The name of the meta variable.
+             */
+            void addMetaVariable(std::string const& name);
+            
+            /*!
+             * Adds integer meta variables with the given names and (equal) range and arranges the DD variables in an
+             * interleaved order.
              *
              * @param names The names of the variables.
              * @param low The lowest value of the ranges of the variables.
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
index 9132eab03..453b83cc8 100644
--- a/src/storage/dd/DdMetaVariable.cpp
+++ b/src/storage/dd/DdMetaVariable.cpp
@@ -4,7 +4,15 @@
 namespace storm {
     namespace dd {
         template<DdType Type>
-        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
+        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), type(MetaVariableType::Int), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
+            // Create the cube of all variables of this meta variable.
+            for (auto const& ddVariable : this->ddVariables) {
+                this->cube *= ddVariable;
+            }
+        }
+        
+        template<DdType Type>
+        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), type(MetaVariableType::Bool), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
             // Create the cube of all variables of this meta variable.
             for (auto const& ddVariable : this->ddVariables) {
                 this->cube *= ddVariable;
@@ -16,6 +24,11 @@ namespace storm {
             return this->name;
         }
         
+        template<DdType Type>
+        typename DdMetaVariable<Type>::MetaVariableType DdMetaVariable<Type>::getType() const {
+            return this->type;
+        }
+        
         template<DdType Type>
         int_fast64_t DdMetaVariable<Type>::getLow() const {
             return this->low;
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index f6c90cc21..47936d805 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -8,6 +8,7 @@
 
 #include "utility/OsDetection.h"
 #include "src/storage/dd/CuddDd.h"
+#include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace dd {
@@ -20,9 +21,13 @@ namespace storm {
             // Declare the DdManager class as friend so it can access the internals of a meta variable.
             friend class DdManager<Type>;
             friend class Dd<Type>;
+            friend class DdForwardIterator<Type>;
+            
+            // An enumeration for all legal types of meta variables.
+            enum class MetaVariableType { Bool, Int };
             
             /*!
-             * Creates a meta variable with the given name, range bounds.
+             * Creates an integer meta variable with the given name and range bounds.
              *
              * @param name The name of the meta variable.
              * @param low The lowest value of the range of the variable.
@@ -32,6 +37,14 @@ namespace storm {
              */
             DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
             
+            /*!
+             * Creates a boolean meta variable with the given name.
+             * @param name The name of the meta variable.
+             * @param ddVariables The vector of variables used to encode this variable.
+             * @param manager A pointer to the manager that is responsible for this meta variable.
+             */
+            DdMetaVariable(std::string const& name, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
+            
             // Explictly generate all default versions of copy/move constructors/assignments.
             DdMetaVariable(DdMetaVariable const& other) = default;
 			DdMetaVariable& operator=(DdMetaVariable const& other) = default;
@@ -47,6 +60,13 @@ namespace storm {
              */
             std::string const& getName() const;
             
+            /*!
+             * Retrieves the type of the meta variable.
+             *
+             * @return The type of the meta variable.
+             */
+            MetaVariableType getType() const;
+            
             /*!
              * Retrieves the lowest value of the range of the variable.
              *
@@ -93,6 +113,9 @@ namespace storm {
             // The name of the meta variable.
             std::string name;
             
+            // The type of the variable.
+            MetaVariableType type;
+            
             // The lowest value of the range of the variable.
             int_fast64_t low;
             
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index fb6f0088c..c1d4862a6 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -1,6 +1,7 @@
-#include "src/storage/expressions/SimpleValuation.h"
-
 #include <boost/functional/hash.hpp>
+#include "src/storage/expressions/SimpleValuation.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidArgumentException.h"
 
 namespace storm {
     namespace expressions {
@@ -13,16 +14,22 @@ namespace storm {
         }
         
         void SimpleValuation::addBooleanIdentifier(std::string const& name, bool initialValue) {
+            LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Boolean identifier '" << name << "' already registered.");
+            
             this->booleanIdentifierToIndexMap->emplace(name, this->booleanValues.size());
             this->booleanValues.push_back(false);
         }
         
         void SimpleValuation::addIntegerIdentifier(std::string const& name, int_fast64_t initialValue) {
+            LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Integer identifier '" << name << "' already registered.");
+
             this->integerIdentifierToIndexMap->emplace(name, this->integerValues.size());
             this->integerValues.push_back(initialValue);
         }
         
         void SimpleValuation::addDoubleIdentifier(std::string const& name, double initialValue) {
+            LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Double identifier '" << name << "' already registered.");
+
             this->doubleIdentifierToIndexMap->emplace(name, this->doubleValues.size());
             this->doubleValues.push_back(initialValue);
         }
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index c405006d8..3ca7c0ce1 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -273,3 +273,24 @@ TEST(CuddDd, GetSetValueTest) {
     metaVariableToValueMap.emplace("x", 4);
     EXPECT_EQ(2, dd1.getValue(metaVariableToValueMap));
 }
+
+TEST(CuddDd, ForwardIteratorTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
+    manager->addMetaVariable("x", 1, 9);
+    manager->addMetaVariable("y", 0, 3);
+    
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd;
+    ASSERT_NO_THROW(dd = manager->getRange("x"));
+    
+    storm::dd::DdForwardIterator<storm::dd::DdType::CUDD> it, ite;
+    ASSERT_NO_THROW(it = dd.begin());
+    ASSERT_NO_THROW(ite = dd.end());
+    std::pair<storm::expressions::SimpleValuation, double> valuationValuePair;
+    uint_fast64_t numberOfValuations = 0;
+    while (it != ite) {
+        ASSERT_NO_THROW(valuationValuePair = *it);
+        ASSERT_NO_THROW(++it);
+        ++numberOfValuations;
+    }
+    EXPECT_EQ(9, numberOfValuations);
+}

From 63601e0b8a39b06ba0ecd7e5e0170db36164014a Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 22 Apr 2014 14:14:06 +0200
Subject: [PATCH 089/147] Calling getExpression on an undefined constant is now
 properly treated with an exception.

Former-commit-id: 2d3e06a20af6d7170db29cd046668951e2c3567d
---
 src/storage/prism/Constant.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 3df0a26bc..641336c76 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -1,4 +1,6 @@
 #include "src/storage/prism/Constant.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/IllegalFunctionCallException.h"
 
 namespace storm {
     namespace prism {
@@ -23,6 +25,7 @@ namespace storm {
         }
         
         storm::expressions::Expression const& Constant::getExpression() const {
+            LOG_THROW(this->isDefined(), storm::exceptions::IllegalFunctionCallException, "Unable to retrieve defining expression for undefined constant.");
             return this->expression;
         }
         

From 39ec9401ef67f7fe96df45b4b7a44c7650c7ee6f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 23 Apr 2014 13:23:53 +0200
Subject: [PATCH 090/147] Fixed the PrismParser so the exact format of PRISMs
 boolean expressions can now be parsed.

Former-commit-id: bb08ec1646a7890cc768b4b4462c0af613d079b4
---
 src/parser/PrismParser.cpp                    | 36 +++++++++----------
 src/parser/PrismParser.h                      |  5 ++-
 .../BinaryBooleanFunctionExpression.cpp       |  4 +--
 test/functional/parser/PrismParserTest.cpp    |  2 +-
 4 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 33373782e..ed15050cb 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -88,10 +88,13 @@ namespace storm {
             plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
             plusExpression.name("plus expression");
             
-            relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createNotEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
+            relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
             relativeExpression.name("relative expression");
             
-            andExpression = relativeExpression[qi::_val = qi::_1] >> *((qi::lit("&")[qi::_a = storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And] | qi::lit("<=>")[qi::_a = storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff] | qi::lit("^")[qi::_a = storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Xor]) >> relativeExpression)[phoenix::if_(qi::_a == storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And) [ qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [ phoenix::if_(qi::_a == storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff) [ qi::_val = phoenix::bind(&PrismParser::createIffExpression, phoenix::ref(*this), qi::_val, qi::_1) ] .else_ [ qi::_val = phoenix::bind(&PrismParser::createXorExpression, phoenix::ref(*this), qi::_val, qi::_1) ] ] ];
+            equalityExpression = relativeExpression[qi::_val = qi::_1] >> *((qi::lit("=")[qi::_a = true] | qi::lit("!=")[qi::_a = false]) >> relativeExpression)[phoenix::if_(qi::_a) [ qi::_val = phoenix::bind(&PrismParser::createEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] .else_ [ qi::_val = phoenix::bind(&PrismParser::createNotEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] ];
+            equalityExpression.name("equality expression");
+            
+            andExpression = equalityExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> equalityExpression)[qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
             andExpression.name("and expression");
             
             orExpression = andExpression[qi::_val = qi::_1] >> *((qi::lit("|")[qi::_a = true] | qi::lit("=>")[qi::_a = false]) >> andExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createImpliesExpression, phoenix::ref(*this), qi::_val, qi::_1)] ];
@@ -204,6 +207,7 @@ namespace storm {
             qi::on_error<qi::fail>(iteExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(equalityExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
@@ -327,27 +331,15 @@ namespace storm {
             }
         }
         
-        storm::expressions::Expression PrismParser::createIffExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                return e1.iff(e2);
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createXorExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                return e1 ^ e2;
-            }
-        }
-        
         storm::expressions::Expression PrismParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 == e2;
+                if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
+                    return e1.iff(e2);
+                } else {
+                    return e1 == e2;
+                }
             }
         }
         
@@ -355,7 +347,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 != e2;
+                if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
+                    return e1 ^ e2;
+                } else {
+                    return e1 != e2;
+                }
             }
         }
         
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 15acef30b..4a0eec392 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -246,8 +246,9 @@ namespace storm {
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> iteExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> orExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<storm::expressions::BinaryBooleanFunctionExpression::OperatorType>, Skipper> andExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> equalityExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
@@ -277,8 +278,6 @@ namespace storm {
             storm::expressions::Expression createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createIffExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createXorExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index d5d6694ab..02cd9686b 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -90,9 +90,9 @@ namespace storm {
             switch (this->getOperatorType()) {
                 case OperatorType::And: stream << " & "; break;
                 case OperatorType::Or: stream << " | "; break;
-                case OperatorType::Xor: stream << " ^ "; break;
+                case OperatorType::Xor: stream << " != "; break;
                 case OperatorType::Implies: stream << " => "; break;
-                case OperatorType::Iff: stream << " <=> "; break;
+                case OperatorType::Iff: stream << " = "; break;
             }
             stream << *this->getSecondOperand() << ")";
         }
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index 381ca3e1b..81731114b 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -47,7 +47,7 @@ TEST(PrismParser, SimpleFullTest) {
     R"(dtmc
     module mod1
         b : bool;
-        [a] true -> 1: (b'=true ^ false <=> b => false);
+        [a] true -> 1: (b'=true != false = b => false);
     endmodule)";
     
     storm::prism::Program result;

From 3eb8f8e3288844fd1c8b61f0245582e0300ff312 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 23 Apr 2014 14:52:44 +0200
Subject: [PATCH 091/147] Bugfix: valuations now correctly store the given
 initial value for boolean variables.

Former-commit-id: a23f0143039cfa7938ed0f709826b79f630d2ada
---
 src/storage/expressions/SimpleValuation.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index c1d4862a6..d29e6a7c8 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -17,7 +17,7 @@ namespace storm {
             LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Boolean identifier '" << name << "' already registered.");
             
             this->booleanIdentifierToIndexMap->emplace(name, this->booleanValues.size());
-            this->booleanValues.push_back(false);
+            this->booleanValues.push_back(initialValue);
         }
         
         void SimpleValuation::addIntegerIdentifier(std::string const& name, int_fast64_t initialValue) {

From 5b06259a05ff524d17a570df035c1f13f7eeb409 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 23 Apr 2014 16:09:33 +0200
Subject: [PATCH 092/147] Added ite operator for DDs in abstraction layer.

Former-commit-id: b1bc85e9e3f26bf1bf9c99a987af56a8dd2d42d8
---
 src/storage/dd/CuddDd.cpp | 8 ++++++++
 src/storage/dd/CuddDd.h   | 7 +++++++
 2 files changed, 15 insertions(+)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index c1f42c0db..4daf835a6 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -20,6 +20,14 @@ namespace storm {
             return this->cuddAdd != other.getCuddAdd();
         }
         
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::ite(Dd<DdType::CUDD> const& thenDd, Dd<DdType::CUDD> const& elseDd) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(thenDd.getContainedMetaVariableNames().begin(), thenDd.getContainedMetaVariableNames().end());
+            metaVariableNames.insert(elseDd.getContainedMetaVariableNames().begin(), elseDd.getContainedMetaVariableNames().end());
+            
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Ite(thenDd.getCuddAdd(), elseDd.getCuddAdd()));
+        }
+        
         Dd<DdType::CUDD> Dd<DdType::CUDD>::operator+(Dd<DdType::CUDD> const& other) const {
             Dd<DdType::CUDD> result(*this);
             result += other;
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 33318ed38..32762b6cb 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -50,6 +50,13 @@ namespace storm {
              */
             bool operator!=(Dd<DdType::CUDD> const& other) const;
             
+            /*!
+             * Performs an if-then-else with the given operands, i.e. maps all valuations that are mapped to a non-zero
+             * function value to the function values specified by the first DD and all others to the function values
+             * specified by the second DD.
+             */
+            Dd<DdType::CUDD> ite(Dd<DdType::CUDD> const& thenDd, Dd<DdType::CUDD> const& elseDd) const;
+            
             /*!
              * Performs a logical or of the current and the given DD.
              *

From 8d3ed7d2fae31bd4022df5b942a5dacbea416e17 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 24 Apr 2014 14:03:36 +0200
Subject: [PATCH 093/147] Added min/max functions on DDs. Added tests for them
 and ite operation.

Former-commit-id: 8e6df90a385c5d840a51288e6b23237f3b8dc11d
---
 src/storage/dd/CuddDd.cpp              | 16 +++++++++++++++-
 src/storage/dd/CuddDd.h                | 16 ++++++++++++++++
 test/functional/storage/CuddDdTest.cpp | 14 ++++++++++++++
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 4daf835a6..bbce93902 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -25,7 +25,7 @@ namespace storm {
             metaVariableNames.insert(thenDd.getContainedMetaVariableNames().begin(), thenDd.getContainedMetaVariableNames().end());
             metaVariableNames.insert(elseDd.getContainedMetaVariableNames().begin(), elseDd.getContainedMetaVariableNames().end());
             
-            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Ite(thenDd.getCuddAdd(), elseDd.getCuddAdd()));
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Ite(thenDd.getCuddAdd(), elseDd.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::operator+(Dd<DdType::CUDD> const& other) const {
@@ -153,6 +153,20 @@ namespace storm {
             return result;
         }
         
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::minimum(Dd<DdType::CUDD> const& other) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Minimum(other.getCuddAdd()), metaVariableNames);
+        }
+
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::maximum(Dd<DdType::CUDD> const& other) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Maximum(other.getCuddAdd()), metaVariableNames);
+        }
+
         void Dd<DdType::CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 32762b6cb..6c7bffd6a 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -210,6 +210,22 @@ namespace storm {
              */
             Dd<DdType::CUDD> greaterOrEqual(Dd<DdType::CUDD> const& other) const;
             
+            /*!
+             * Retrieves the function that maps all evaluations to the minimum of the function values of the two DDs.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<DdType::CUDD> minimum(Dd<DdType::CUDD> const& other) const;
+
+            /*!
+             * Retrieves the function that maps all evaluations to the maximum of the function values of the two DDs.
+             *
+             * @param other The DD with which to perform the operation.
+             * @return The resulting function represented as a DD.
+             */
+            Dd<DdType::CUDD> maximum(Dd<DdType::CUDD> const& other) const;
+
             /*!
              * Existentially abstracts from the given meta variables.
              *
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 3ca7c0ce1..91d14f202 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -178,6 +178,20 @@ TEST(CuddDd, OperatorTest) {
     dd3 = dd1.greaterOrEqual(dd2);
     EXPECT_EQ(5, dd3.getNonZeroCount());
     
+    dd3 = (manager->getEncoding("x", 2)).ite(dd2, dd1);
+    dd4 = dd3.less(dd2);
+    EXPECT_EQ(10, dd4.getNonZeroCount());
+    
+    dd4 = dd3.minimum(dd1);
+    dd4 *= manager->getEncoding("x", 2);
+    dd4.sumAbstract({"x"});
+    EXPECT_EQ(2, dd4.getValue());
+
+    dd4 = dd3.maximum(dd1);
+    dd4 *= manager->getEncoding("x", 2);
+    dd4.sumAbstract({"x"});
+    EXPECT_EQ(5, dd4.getValue());
+
     dd1 = manager->getConstant(0.01);
     dd2 = manager->getConstant(0.01 + 1e-6);
     EXPECT_TRUE(dd1.equalModuloPrecision(dd2, 1e-6, false));

From 44ba492fe707d8e575c6844eb898f3a1361773d5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 25 Apr 2014 13:13:03 +0200
Subject: [PATCH 094/147] CuddDdManager now sets tolerance to 1e-15.

Former-commit-id: bfc985b5defbfc33bf0337140c5a5f978ae5f4bb
---
 src/storage/dd/CuddDdManager.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index c75a7c211..6c8c66683 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -8,7 +8,8 @@
 namespace storm {
     namespace dd {
         DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
-            // Intentionally left empty.
+            
+            this->cuddManager.SetEpsilon(1.0e-15);
         }
         
         Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() {

From 5816bd8860d80777513957bbe1ae408e64169150 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 29 Apr 2014 16:37:53 +0200
Subject: [PATCH 095/147] Bugfix for explicit model adapter: empty choice
 labeling was not created for automatically added self-loops.

Former-commit-id: 6c63c28f596905583d0695a7dcdad8bbdd57d7bd
---
 src/adapters/ExplicitModelAdapter.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h
index 777807c06..e120f4a59 100644
--- a/src/adapters/ExplicitModelAdapter.h
+++ b/src/adapters/ExplicitModelAdapter.h
@@ -559,6 +559,8 @@ namespace storm {
                     // requested and issue an error otherwise.
                     if (totalNumberOfChoices == 0) {
                         if (storm::settings::Settings::getInstance()->isSet("fixDeadlocks")) {
+                            // Insert empty choice labeling for added self-loop transitions.
+                            choiceLabels.push_back(boost::container::flat_set<uint_fast64_t>());
                             transitionMatrixBuilder.addNextValue(currentRow, currentState, storm::utility::constantOne<ValueType>());
                             ++currentRow;
                         } else {

From d0d80cf5e1986596ee0b06e663021fd048c0f6f3 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 1 May 2014 11:49:49 +0200
Subject: [PATCH 096/147] Started on making the PrismParser more robust.

Former-commit-id: 7ce1351d0c7221ef303052d9ab1264f2baaa5f50
---
 src/parser/PrismParser.h | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 4a0eec392..6a31ef367 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -27,9 +27,11 @@ typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost:
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/Expressions.h"
 #include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
     namespace parser {
+        // A class that stores information about the parsed program.
         class GlobalProgramInformation {
         public:
             // Default construct the header information.
@@ -117,13 +119,7 @@ namespace storm {
                 
                 template<typename T1, typename T2, typename T3, typename T4>
                 qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
-                    //                    LOG4CPLUS_ERROR(logger, "Error: expecting " << what << " in line " << get_line(where) << " at column " << get_column(b, where, 4) << ".");
-                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << "." << std::endl;
-                    T3 end(where);
-                    while (end != e && *end != '\r' && *end != '\n') {
-                        ++end;
-                    }
-                    std::cerr << "Error: expecting " << what << " in line " << get_line(where) << ": \n" << std::string(get_line_start(b, where), end) << " ... \n" << std::setw(std::distance(b, where)) << '^' << "---- here\n";
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(where) << ": " << " expecting " << what << ".");
                     return qi::fail;
                 }
             };

From 6f9dd7107d77b2c5e931698bd4064737fe753112 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 1 May 2014 14:14:25 +0200
Subject: [PATCH 097/147] Added universal abstraction function to DD layer.

Former-commit-id: 56e5d62b5a780a138ebbfb4276012153d27517e1
---
 src/storage/dd/CuddDd.cpp | 17 +++++++++++++++++
 src/storage/dd/CuddDd.h   |  7 +++++++
 2 files changed, 24 insertions(+)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index bbce93902..72abb87bf 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -184,6 +184,23 @@ namespace storm {
             this->cuddAdd = this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
         }
         
+        void Dd<DdType::CUDD>::universalAbstract(std::set<std::string> const& metaVariableNames) {
+            Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
+            
+            for (auto const& metaVariableName : metaVariableNames) {
+                // First check whether the DD contains the meta variable and erase it, if this is the case.
+                if (!this->containsMetaVariable(metaVariableName)) {
+                    throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
+                }
+                this->getContainedMetaVariableNames().erase(metaVariableName);
+                
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                cubeDd *= metaVariable.getCube();
+            }
+            
+            this->cuddAdd = this->cuddAdd.UnivAbstract(cubeDd.getCuddAdd());
+        }
+        
         void Dd<DdType::CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 6c7bffd6a..f345c28a2 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -233,6 +233,13 @@ namespace storm {
              */
             void existsAbstract(std::set<std::string> const& metaVariableNames);
             
+            /*!
+             * Universally abstracts from the given meta variables.
+             *
+             * @param metaVariableNames The names of all meta variables from which to abstract.
+             */
+            void universalAbstract(std::set<std::string> const& metaVariableNames);
+            
             /*!
              * Sum-abstracts from the given meta variables.
              *

From 82836f1ad1d5ad06fd0541636b130a1377135819 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 2 May 2014 00:01:14 +0200
Subject: [PATCH 098/147] Added some checks for validity of identifiers in
 PRISM programs. Added some illegal tests to test suite.

Former-commit-id: fc44db75a74221692e6a1ec36ec4f15a8892b17f
---
 src/parser/PrismParser.cpp                 | 67 +++++++++++++-----
 src/parser/PrismParser.h                   |  2 +-
 test/functional/parser/PrismParserTest.cpp | 79 ++++++++++++++++++++++
 3 files changed, 129 insertions(+), 19 deletions(-)

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index ed15050cb..b96a0b823 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -147,13 +147,7 @@ namespace storm {
             
             globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)]));
             globalVariableDefinition.name("global variable declaration list");
-            
-            programHeader = modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
-            >   *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)] | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)])
-            >   *(formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1)])
-            >   *(globalVariableDefinition(qi::_r1));
-            programHeader.name("program header");
-            
+                        
             stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
             stateRewardDefinition.name("state reward definition");
             
@@ -199,7 +193,19 @@ namespace storm {
             moduleDefinitionList %= +(moduleRenaming(qi::_r1) | moduleDefinition(qi::_r1))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_r1), qi::_1)];
             moduleDefinitionList.name("module list");
             
-            start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(initialStatesConstruct(qi::_a) | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)] | formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_a), qi::_1)]) > qi::eoi)[qi::_val = phoenix::bind(&PrismParser::createProgram, phoenix::ref(*this), qi::_a)];
+            start = (qi::eps
+                     > modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_a) = qi::_1]
+                     > *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_a), qi::_1)] 
+                         | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_a), qi::_1)]
+                         | formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_a), qi::_1)]
+                         | globalVariableDefinition(qi::_a)
+                         | (moduleRenaming(qi::_a) | moduleDefinition(qi::_a))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_a), qi::_1)]
+                         | initialStatesConstruct(qi::_a)
+                         | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] 
+                         | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)] 
+                         | formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_a), qi::_1)]
+                     )
+                     > qi::eoi)[qi::_val = phoenix::bind(&PrismParser::createProgram, phoenix::ref(*this), qi::_a)];
             start.name("probabilistic program");
             
             // Enable error reporting.
@@ -258,7 +264,7 @@ namespace storm {
         }
         
         bool PrismParser::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
-            LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::InvalidArgumentException, "Program must not define two initial constructs.");
+            LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::WrongFormatException, "Program must not define two initial constructs.");
             if (globalProgramInformation.hasInitialStatesExpression) {
                 return false;
             }
@@ -483,37 +489,56 @@ namespace storm {
         }
         
         storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
-            this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+            }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
-            this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+            }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
-            this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+            }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
-            this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+            }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, expression, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
-            this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+            }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, expression, this->getFilename());
         }
         
         storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
-            this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+            }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, expression, this->getFilename());
         }
         
         storm::prism::Formula PrismParser::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
-            if (this->secondRun) {
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(formulaName) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << formulaName << "'.");
                 this->identifiers_.add(formulaName, expression);
             }
             return storm::prism::Formula(formulaName, expression, this->getFilename());
@@ -550,12 +575,18 @@ namespace storm {
         }
         
         storm::prism::BooleanVariable PrismParser::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const {
-            this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(variableName) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << variableName << "'.");
+                this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
+            }
             return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename());
         }
         
         storm::prism::IntegerVariable PrismParser::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const {
-            this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
+            if (!this->secondRun) {
+                LOG_THROW(this->identifiers_.find(variableName) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << variableName << "'.");
+                this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
+            }
             return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename());
         }
         
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 6a31ef367..b5013eee8 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -189,7 +189,7 @@ namespace storm {
             qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
             
             // Rules for parsing the program header.
-            qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
+
             qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
             qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
             qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index 81731114b..dca09244a 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -54,6 +54,21 @@ TEST(PrismParser, SimpleFullTest) {
     EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true));
     EXPECT_EQ(1, result.getNumberOfModules());
     EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType());
+    
+    testInput =
+    R"(mdp
+    
+    module main
+        x : [1..5] init 1;
+        [] x=1 -> 1:(x'=2);
+        [] x=2 -> 1:(x'=3);
+        [] x=3 -> 1:(x'=1);
+        [] x=3 -> 1:(x'=4);
+        [] x=4 -> 1:(x'=5);
+    endmodule)";
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true));
+    EXPECT_EQ(1, result.getNumberOfModules());
+    EXPECT_EQ(storm::prism::Program::ModelType::MDP, result.getModelType());
 }
 
 TEST(PrismParser, ComplexFullTest) {
@@ -167,4 +182,68 @@ TEST(PrismParser, ComplexParsingTest) {
     EXPECT_EQ(2, result.getNumberOfRewardModels());
     EXPECT_EQ(1, result.getNumberOfLabels());
     EXPECT_TRUE(result.definesInitialStatesExpression());
+}
+
+TEST(PrismParser, IllegalInputTest) {
+    std::string testInput =
+    R"(ctmc
+
+    const int a;
+    const bool a = true;
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c < 3 -> 2: (c' = c+1); 
+    endmodule
+    )";
+    
+    storm::prism::Program result;
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    const int a;
+    
+    module mod1
+        a : [0 .. 8] init 1;
+        [] a < 3 -> 1: (a' = a+1); 
+    endmodule)";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    const int a = 2;
+    formula a = 41;
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c < 3 -> 1: (c' = c+1); 
+    endmodule)";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    const int a = 2;
+    
+    init
+        c > 3
+    endinit
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c < 3 -> 1: (c' = c+1); 
+    endmodule
+        
+    init
+        c > 3
+    endinit
+
+    )";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
 }
\ No newline at end of file

From 873d80cd2d0bc279c7a99e512756924ae80f6b75 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 3 May 2014 13:20:25 +0200
Subject: [PATCH 099/147] If a module is renamed from some other module, this
 is now kept track of in the respective PRISM classes.

Former-commit-id: c07e25ac55e86520522047ad4b7bc394fd36b556
---
 src/parser/PrismParser.cpp   | 169 ++++++++++++++++++++++++++---------
 src/parser/PrismParser.h     |   1 -
 src/storage/prism/Module.cpp |  21 ++++-
 src/storage/prism/Module.h   |  47 +++++++++-
 4 files changed, 191 insertions(+), 47 deletions(-)

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index b96a0b823..ffda5e219 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -1,5 +1,6 @@
 #include "src/parser/PrismParser.h"
 #include "src/exceptions/InvalidArgumentException.h"
+#include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
@@ -7,7 +8,7 @@ namespace storm {
         storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) {
             // Open file and initialize result.
             std::ifstream inputFileStream(filename, std::ios::in);
-            LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file " << filename << ".");
+            LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
             
             storm::prism::Program result;
             
@@ -264,7 +265,7 @@ namespace storm {
         }
         
         bool PrismParser::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
-            LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::WrongFormatException, "Program must not define two initial constructs.");
+            LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Program must not define two initial constructs.");
             if (globalProgramInformation.hasInitialStatesExpression) {
                 return false;
             }
@@ -277,7 +278,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1.ite(e2, e3);
+                try {
+                    return e1.ite(e2, e3);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -285,7 +290,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1.implies(e2);
+                try {
+                    return e1.implies(e2);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -293,7 +302,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 || e2;
+                try {
+                    return e1 || e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -301,7 +314,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 && e2;
+                try{
+                    return e1 && e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -309,7 +326,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 > e2;
+                try {
+                    return e1 > e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -317,7 +338,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 >= e2;
+                try {
+                    return e1 >= e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -325,7 +350,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 < e2;
+                try {
+                    return e1 < e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -333,7 +362,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 <= e2;
+                try {
+                    return e1 <= e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -341,10 +374,14 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
-                    return e1.iff(e2);
-                } else {
-                    return e1 == e2;
+                try {
+                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
+                        return e1.iff(e2);
+                    } else {
+                        return e1 == e2;
+                    }
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
                 }
             }
         }
@@ -353,10 +390,14 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
-                    return e1 ^ e2;
-                } else {
-                    return e1 != e2;
+                try {
+                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
+                        return e1 ^ e2;
+                    } else {
+                        return e1 != e2;
+                    }
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
                 }
             }
         }
@@ -365,7 +406,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 + e2;
+                try {
+                    return e1 + e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -373,7 +418,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 - e2;
+                try {
+                    return e1 - e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -381,7 +430,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 * e2;
+                try {
+                    return e1 * e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -389,7 +442,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1 / e2;
+                try {
+                    return e1 / e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -397,7 +454,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return !e1;
+                try {
+                    return !e1;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -405,7 +466,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return -e1;
+                try {
+                    return -e1;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -450,7 +515,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return storm::expressions::Expression::minimum(e1, e2);
+                try {
+                    return storm::expressions::Expression::minimum(e1, e2);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -458,7 +527,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return storm::expressions::Expression::maximum(e1, e2);
+                try {
+                    return storm::expressions::Expression::maximum(e1, e2);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -466,7 +539,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1.floor();
+                try {
+                    return e1.floor();
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -474,7 +551,11 @@ namespace storm {
             if (!this->secondRun) {
                 return storm::expressions::Expression::createFalse();
             } else {
-                return e1.ceil();
+                try {
+                    return e1.ceil();
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
             }
         }
         
@@ -483,14 +564,14 @@ namespace storm {
                 return storm::expressions::Expression::createFalse();
             } else {
                 storm::expressions::Expression const* expression = this->identifiers_.find(identifier);
-                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Undeclared identifier '" << identifier << "'.");
+                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'.");
                 return *expression;
             }
         }
         
         storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
                 this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, this->getFilename());
@@ -498,7 +579,7 @@ namespace storm {
         
         storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
                 this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, this->getFilename());
@@ -506,7 +587,7 @@ namespace storm {
         
         storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
                 this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, this->getFilename());
@@ -514,7 +595,7 @@ namespace storm {
         
         storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
                 this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, expression, this->getFilename());
@@ -522,7 +603,7 @@ namespace storm {
         
         storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
                 this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, expression, this->getFilename());
@@ -530,7 +611,7 @@ namespace storm {
         
         storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << newConstant << "'.");
+                LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
                 this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, expression, this->getFilename());
@@ -538,7 +619,7 @@ namespace storm {
         
         storm::prism::Formula PrismParser::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(formulaName) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << formulaName << "'.");
+                LOG_THROW(this->identifiers_.find(formulaName) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << formulaName << "'.");
                 this->identifiers_.add(formulaName, expression);
             }
             return storm::prism::Formula(formulaName, expression, this->getFilename());
@@ -576,7 +657,7 @@ namespace storm {
         
         storm::prism::BooleanVariable PrismParser::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(variableName) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << variableName << "'.");
+                LOG_THROW(this->identifiers_.find(variableName) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << variableName << "'.");
                 this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
             }
             return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename());
@@ -584,7 +665,7 @@ namespace storm {
         
         storm::prism::IntegerVariable PrismParser::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const {
             if (!this->secondRun) {
-                LOG_THROW(this->identifiers_.find(variableName) == nullptr, storm::exceptions::WrongFormatException, "Duplicate identifier '" << variableName << "'.");
+                LOG_THROW(this->identifiers_.find(variableName) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << variableName << "'.");
                 this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
             }
             return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename());
@@ -598,19 +679,19 @@ namespace storm {
         storm::prism::Module PrismParser::createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const {
             // Check whether the module to rename actually exists.
             auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
-            LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "No module named '" << oldModuleName << "' to rename.");
+            LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": No module named '" << oldModuleName << "' to rename.");
             storm::prism::Module const& moduleToRename = globalProgramInformation.modules[moduleIndexPair->second];
             
             if (!this->secondRun) {
                 // Register all (renamed) variables for later use.
                 for (auto const& variable : moduleToRename.getBooleanVariables()) {
                     auto const& renamingPair = renaming.find(variable.getName());
-                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Boolean variable '" << variable.getName() << " was not renamed.");
                     this->identifiers_.add(renamingPair->second, storm::expressions::Expression::createBooleanVariable(renamingPair->second));
                 }
                 for (auto const& variable : moduleToRename.getIntegerVariables()) {
                     auto const& renamingPair = renaming.find(variable.getName());
-                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Integer variable '" << variable.getName() << " was not renamed.");
                     this->identifiers_.add(renamingPair->second, storm::expressions::Expression::createIntegerVariable(renamingPair->second));
                 }
                 
@@ -634,7 +715,7 @@ namespace storm {
                 std::vector<storm::prism::BooleanVariable> booleanVariables;
                 for (auto const& variable : moduleToRename.getBooleanVariables()) {
                     auto const& renamingPair = renaming.find(variable.getName());
-                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Boolean variable '" << variable.getName() << " was not renamed.");
                     
                     booleanVariables.push_back(storm::prism::BooleanVariable(renamingPair->second, variable.getInitialValueExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1)));
                 }
@@ -643,7 +724,7 @@ namespace storm {
                 std::vector<storm::prism::IntegerVariable> integerVariables;
                 for (auto const& variable : moduleToRename.getIntegerVariables()) {
                     auto const& renamingPair = renaming.find(variable.getName());
-                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
+                    LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Integer variable '" << variable.getName() << " was not renamed.");
                     
                     integerVariables.push_back(storm::prism::IntegerVariable(renamingPair->second, variable.getLowerBoundExpression().substitute(expressionRenaming), variable.getUpperBoundExpression().substitute(expressionRenaming), variable.getInitialValueExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1)));
                 }
@@ -676,7 +757,7 @@ namespace storm {
                     ++globalProgramInformation.currentCommandIndex;
                 }
                 
-                return storm::prism::Module(newModuleName, booleanVariables, integerVariables, commands, this->getFilename());
+                return storm::prism::Module(newModuleName, booleanVariables, integerVariables, commands, oldModuleName, renaming);
             }
         }
         
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index b5013eee8..3312768c3 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -189,7 +189,6 @@ namespace storm {
             qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
             
             // Rules for parsing the program header.
-
             qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
             qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
             qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index f17e1bc12..d7b3fb572 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -2,10 +2,15 @@
 #include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/OutOfRangeException.h"
 #include "src/exceptions/InvalidArgumentException.h"
+#include "src/exceptions/InvalidAccessException.h"
 
 namespace storm {
     namespace prism {
-        Module::Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), booleanVariableToIndexMap(), integerVariables(integerVariables), integerVariableToIndexMap(), commands(commands), actions(), actionsToCommandIndexMap() {
+        Module::Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename, uint_fast64_t lineNumber) : Module(moduleName, booleanVariables, integerVariables, commands, "", std::map<std::string, std::string>(), filename, lineNumber) {
+            // Intentionally left empty.
+        }
+        
+        Module::Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& renamedFromModule, std::map<std::string, std::string> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), moduleName(moduleName), booleanVariables(booleanVariables), booleanVariableToIndexMap(), integerVariables(integerVariables), integerVariableToIndexMap(), commands(commands), actions(), actionsToCommandIndexMap(), renamedFromModule(renamedFromModule), renaming(renaming) {
             // Initialize the internal mappings for fast information retrieval.
             this->createMappings();
         }
@@ -71,6 +76,20 @@ namespace storm {
             return actionEntry != this->actions.end();
         }
         
+        bool Module::isRenamedFromModule() const {
+            return this->renamedFromModule != "";
+        }
+        
+        std::string const& Module::getBaseModule() const {
+            LOG_THROW(this->isRenamedFromModule(), storm::exceptions::InvalidAccessException, "Unable to retrieve base module of module that was not created by renaming.");
+            return this->renamedFromModule;
+        }
+        
+        std::map<std::string, std::string> const& Module::getRenaming() const {
+            LOG_THROW(this->isRenamedFromModule(), storm::exceptions::InvalidAccessException, "Unable to retrieve renaming of module that was not created by renaming.");
+            return this->renaming;
+        }
+        
         std::set<uint_fast64_t> const& Module::getCommandIndicesByAction(std::string const& action) const {
             auto actionsCommandSetPair = this->actionsToCommandIndexMap.find(action);
             if (actionsCommandSetPair != this->actionsToCommandIndexMap.end()) {
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index f4fd21f29..1031cbf27 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_PRISM_MODULE_H_
 
 #include <set>
+#include <map>
 #include <string>
 #include <vector>
 #include <memory>
@@ -28,7 +29,22 @@ namespace storm {
              * @param lineNumber The line number in which the module is defined.
              */
             Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& filename = "", uint_fast64_t lineNumber = 0);
-            
+
+            /*!
+             * Creates a module with the given name, variables and commands that is marked as being renamed from the
+             * given module with the given renaming.
+             *
+             * @param moduleName The name of the module.
+             * @param booleanVariables The boolean variables defined by the module.
+             * @param integerVariables The integer variables defined by the module.
+             * @param commands The commands of the module.
+             * @param renamedFromModule The name of the module from which this module was renamed.
+             * @param renaming The renaming of identifiers used to create this module.
+             * @param filename The filename in which the module is defined.
+             * @param lineNumber The line number in which the module is defined.
+             */
+            Module(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, std::string const& renamedFromModule, std::map<std::string, std::string> const& renaming, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+
             // Create default implementations of constructors/assignment.
             Module() = default;
             Module(Module const& other) = default;
@@ -133,6 +149,29 @@ namespace storm {
              */
             bool hasAction(std::string const& action) const;
             
+            /*!
+             * Retrieves whether this module was created from another module via renaming.
+             *
+             * @return True iff the module was created via renaming.
+             */
+            bool isRenamedFromModule() const;
+            
+            /*!
+             * If the module was created via renaming, this method retrieves the name of the module that was used as the
+             * in the base in the renaming process.
+             *
+             * @return The name of the module from which this module was created via renaming.
+             */
+            std::string const& getBaseModule() const;
+            
+            /*!
+             * If the module was created via renaming, this method returns the applied renaming of identifiers used for
+             * the renaming process.
+             *
+             * @return A mapping of identifiers to new identifiers that was used in the renaming process.
+             */
+            std::map<std::string, std::string> const& getRenaming() const;
+            
             /*!
              * Retrieves the indices of all commands within this module that are labelled by the given action.
              *
@@ -188,6 +227,12 @@ namespace storm {
             
             // A map of actions to the set of commands labeled with this action.
             std::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
+            
+            // This string indicates whether and from what module this module was created via renaming.
+            std::string renamedFromModule;
+            
+            // If the module was created by renaming, this mapping contains the provided renaming of identifiers.
+            std::map<std::string, std::string> renaming;
         };
         
     } // namespace prism

From 83f9832e2dce56d65112a2ae1877db7ebdc264b5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 4 May 2014 21:51:05 +0200
Subject: [PATCH 100/147] Added type check visitor to validate types of
 identifiers in expressions. Started writing validation method on PRISM
 program class.

Former-commit-id: 6416bea711db3cc55296f04bda77e0e69ed74491
---
 src/storage/expressions/Expression.cpp        |  24 ++-
 src/storage/expressions/Expression.h          |  23 +++
 .../expressions/SubstitutionVisitor.cpp       |  15 +-
 src/storage/expressions/TypeCheckVisitor.cpp  |  97 ++++++++++
 src/storage/expressions/TypeCheckVisitor.h    |  50 +++++
 src/storage/prism/Program.cpp                 | 181 ++++++++++++++++++
 src/storage/prism/Program.h                   |   6 +
 7 files changed, 378 insertions(+), 18 deletions(-)
 create mode 100644 src/storage/expressions/TypeCheckVisitor.cpp
 create mode 100644 src/storage/expressions/TypeCheckVisitor.h

diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 90570f244..51d085fe4 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -4,6 +4,7 @@
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/SubstitutionVisitor.h"
 #include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
+#include "src/storage/expressions/TypeCheckVisitor.h"
 #include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/ExceptionMacros.h"
 
@@ -28,21 +29,29 @@ namespace storm {
         }
         
 		Expression Expression::substitute(std::map<std::string, Expression> const& identifierToExpressionMap) const {
-            return SubstitutionVisitor< std::map<std::string, Expression> >(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
+            return SubstitutionVisitor<std::map<std::string, Expression>>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
         }
 
 		Expression Expression::substitute(std::unordered_map<std::string, Expression> const& identifierToExpressionMap) const {
-			return SubstitutionVisitor< std::unordered_map<std::string, Expression> >(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
+			return SubstitutionVisitor<std::unordered_map<std::string, Expression>>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
 		}
         
 		Expression Expression::substitute(std::map<std::string, std::string> const& identifierToIdentifierMap) const {
-			return IdentifierSubstitutionVisitor< std::map<std::string, std::string> >(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+			return IdentifierSubstitutionVisitor<std::map<std::string, std::string>>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
         }
 
 		Expression Expression::substitute(std::unordered_map<std::string, std::string> const& identifierToIdentifierMap) const {
-			return IdentifierSubstitutionVisitor< std::unordered_map<std::string, std::string> >(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+			return IdentifierSubstitutionVisitor<std::unordered_map<std::string, std::string>>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
 		}
         
+        void Expression::check(std::map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const {
+            return TypeCheckVisitor<std::map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this->getBaseExpressionPointer().get());
+        }
+
+        void Expression::check(std::unordered_map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const {
+            return TypeCheckVisitor<std::unordered_map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this->getBaseExpressionPointer().get());
+        }
+
         bool Expression::evaluateAsBool(Valuation const* valuation) const {
             return this->getBaseExpression().evaluateAsBool(valuation);
         }
@@ -79,6 +88,13 @@ namespace storm {
             return this->getBaseExpression().getConstants();
         }
         
+        std::set<std::string> Expression::getIdentifiers() const {
+            std::set<std::string> result = this->getConstants();
+            std::set<std::string> variables = this->getVariables();
+            result.insert(variables.begin(), variables.end());
+            return result;
+        }
+        
         BaseExpression const& Expression::getBaseExpression() const {
             return *this->expressionPtr;
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 15936219c..36c367639 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -110,6 +110,22 @@ namespace storm {
 			*/
 			Expression substitute(std::unordered_map<std::string, std::string> const& identifierToIdentifierMap) const;
             
+            /*!
+             * Checks that all identifiers appearing in the expression have the types given by the map. An exception
+             * is thrown in case a violation is found.
+             *
+             * @param identifierToTypeMap A mapping from identifiers to the types that are supposed to have.
+             */
+            void check(std::map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const;
+            
+            /*!
+             * Checks that all identifiers appearing in the expression have the types given by the map. An exception
+             * is thrown in case a violation is found.
+             *
+             * @param identifierToTypeMap A mapping from identifiers to the types that are supposed to have.
+             */
+            void check(std::unordered_map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const;
+            
             /*!
              * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
              * valuation and returns the resulting boolean value. If the return type of the expression is not a boolean
@@ -182,6 +198,13 @@ namespace storm {
              */
             std::set<std::string> getConstants() const;
             
+            /*!
+             * Retrieves the set of all identifiers (constants and variables) that appear in the expression.
+             *
+             * @return The est of all identifiers that appear in the expression.
+             */
+            std::set<std::string> getIdentifiers() const;
+            
             /*!
              * Retrieves the base expression underlying this expression object. Note that prior to calling this, the
              * expression object must be properly initialized.
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index 54b533d49..402febc2e 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -3,20 +3,7 @@
 #include <string>
 
 #include "src/storage/expressions/SubstitutionVisitor.h"
-
-#include "src/storage/expressions/IfThenElseExpression.h"
-#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
-#include "src/storage/expressions/BinaryRelationExpression.h"
-#include "src/storage/expressions/BooleanConstantExpression.h"
-#include "src/storage/expressions/IntegerConstantExpression.h"
-#include "src/storage/expressions/DoubleConstantExpression.h"
-#include "src/storage/expressions/BooleanLiteralExpression.h"
-#include "src/storage/expressions/IntegerLiteralExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
-#include "src/storage/expressions/VariableExpression.h"
-#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/Expressions.h"
 
 namespace storm {
     namespace expressions  {
diff --git a/src/storage/expressions/TypeCheckVisitor.cpp b/src/storage/expressions/TypeCheckVisitor.cpp
new file mode 100644
index 000000000..b1cd6a205
--- /dev/null
+++ b/src/storage/expressions/TypeCheckVisitor.cpp
@@ -0,0 +1,97 @@
+#include "src/storage/expressions/TypeCheckVisitor.h"
+#include "src/storage/expressions/Expressions.h"
+
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
+
+namespace storm {
+    namespace expressions {
+        template<typename MapType>
+        TypeCheckVisitor<MapType>::TypeCheckVisitor(MapType const& identifierToTypeMap) : identifierToTypeMap(identifierToTypeMap) {
+            // Intentionally left empty.
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::check(BaseExpression const* expression) {
+            expression->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(IfThenElseExpression const* expression) {
+            expression->getCondition()->accept(this);
+            expression->getThenExpression()->accept(this);
+            expression->getElseExpression()->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(BinaryBooleanFunctionExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            expression->getSecondOperand()->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(BinaryNumericalFunctionExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            expression->getSecondOperand()->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(BinaryRelationExpression const* expression) {
+            expression->getFirstOperand()->accept(this);
+            expression->getSecondOperand()->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
+            auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
+            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected bool, but found " << expression->getReturnType() << ".");
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
+            auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
+            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected double, but found " << expression->getReturnType() << ".");
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
+            auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
+            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected int, but found " << expression->getReturnType() << ".");
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(VariableExpression const* expression) {
+            auto identifierTypePair = this->identifierToTypeMap.find(expression->getVariableName());
+            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getVariableName() << "'.");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for variable '" << expression->getVariableName() << "': expected " << identifierTypePair->first << ", but found " << expression->getReturnType() << ".");
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(UnaryBooleanFunctionExpression const* expression) {
+            expression->getOperand()->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(UnaryNumericalFunctionExpression const* expression) {
+            expression->getOperand()->accept(this);
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(BooleanLiteralExpression const* expression) {
+            // Intentionally left empty.
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(IntegerLiteralExpression const* expression) {
+            // Intentionally left empty.
+        }
+        
+        template<typename MapType>
+        void TypeCheckVisitor<MapType>::visit(DoubleLiteralExpression const* expression) {
+            // Intentionally left empty.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/TypeCheckVisitor.h b/src/storage/expressions/TypeCheckVisitor.h
new file mode 100644
index 000000000..e39a536a6
--- /dev/null
+++ b/src/storage/expressions/TypeCheckVisitor.h
@@ -0,0 +1,50 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_TYPECHECKVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_TYPECHECKVISITOR_H_
+
+#include <stack>
+
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+
+namespace storm {
+    namespace expressions {
+        template<typename MapType>
+        class TypeCheckVisitor : public ExpressionVisitor {
+        public:
+            /*!
+             * Creates a new type check visitor that uses the given map to check the types of variables and constants.
+             *
+             * @param identifierToTypeMap A mapping from identifiers to expressions.
+             */
+            TypeCheckVisitor(MapType const& identifierToTypeMap);
+            
+            /*!
+             * Checks that the types of the identifiers in the given expression match the ones in the previously given
+             * map.
+             *
+             * @param expression The expression in which to check the types.
+             */
+            void check(BaseExpression const* expression);
+            
+            virtual void visit(IfThenElseExpression const* expression) override;
+            virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BinaryRelationExpression const* expression) override;
+            virtual void visit(BooleanConstantExpression const* expression) override;
+            virtual void visit(DoubleConstantExpression const* expression) override;
+            virtual void visit(IntegerConstantExpression const* expression) override;
+            virtual void visit(VariableExpression const* expression) override;
+            virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BooleanLiteralExpression const* expression) override;
+            virtual void visit(IntegerLiteralExpression const* expression) override;
+            virtual void visit(DoubleLiteralExpression const* expression) override;
+            
+        private:            
+            // A mapping of identifier names to expressions with which they shall be replaced.
+            MapType const& identifierToTypeMap;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_TYPECHECKVISITOR_H_ */
\ No newline at end of file
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 1c4118b8b..5e024cd53 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -1,7 +1,11 @@
 #include "src/storage/prism/Program.h"
+
+#include <algorithm>
+
 #include "src/exceptions/ExceptionMacros.h"
 #include "exceptions/InvalidArgumentException.h"
 #include "src/exceptions/OutOfRangeException.h"
+#include "src/exceptions/WrongFormatException.h"
 
 namespace storm {
     namespace prism {
@@ -317,6 +321,183 @@ namespace storm {
             return Program(this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
         }
         
+        void Program::checkValidity() const {
+            // We need to construct a mapping from identifiers to their types, so we can type-check the expressions later.
+            std::map<std::string, storm::expressions::ExpressionReturnType> identifierToTypeMap;
+            
+            // Start by checking the constant declarations.
+            std::set<std::string> allIdentifiers;
+            std::set<std::string> constantNames;
+            for (auto const& constant : this->getConstants()) {
+                // Check for duplicate identifiers.
+                LOG_THROW(allIdentifiers.find(constant.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": duplicate identifier '" << constant.getName() << "'.");
+                
+                // Check defining expressions of defined constants.
+                if (constant.isDefined()) {
+                    LOG_THROW(constant.getExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": definition of constant " << constant.getName() << " must not refer to variables.");
+                    
+                    std::set<std::string> containedConstantNames = constant.getExpression().getConstants();
+                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstantNames.begin(), containedConstantNames.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": defining expression refers to unknown constants.");
+                    
+                    // Now check that the constants appear with the right types (this throws an exception if this is not
+                    // the case).
+                    constant.getExpression().check(identifierToTypeMap);
+                }
+                
+                // Finally, register the type of the constant for later type checks.
+                identifierToTypeMap.emplace(constant.getName(), constant.getType());
+                
+                // Record the new identifier for future checks.
+                constantNames.insert(constant.getName());
+                allIdentifiers.insert(constant.getName());
+            }
+            
+            // Now we check the variable declarations. We start with the global variables.
+            std::set<std::string> variableNames;
+            for (auto const& variable : this->getGlobalBooleanVariables()) {
+                // Check for duplicate identifiers.
+                LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
+                
+                // Check the initial value of the variable.
+                LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
+                std::set<std::string> containedConstants = variable.getInitialValueExpression().getConstants();
+                bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
+                variable.getInitialValueExpression().check(identifierToTypeMap);
+
+                // Register the type of the constant for later type checks.
+                identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Bool);
+                
+                // Record the new identifier for future checks.
+                variableNames.insert(variable.getName());
+                allIdentifiers.insert(variable.getName());
+            }
+            for (auto const& variable : this->getGlobalIntegerVariables()) {
+                // Check for duplicate identifiers.
+                LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
+                
+                // Check that bound expressions of the range.
+                LOG_THROW(variable.getLowerBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression must not refer to variables.");
+                std::set<std::string> containedConstants = variable.getLowerBoundExpression().getConstants();
+                bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression refers to unknown constants.");
+                variable.getLowerBoundExpression().check(identifierToTypeMap);
+                LOG_THROW(variable.getUpperBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression must not refer to variables.");
+                containedConstants = variable.getLowerBoundExpression().getConstants();
+                isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants.");
+                variable.getUpperBoundExpression().check(identifierToTypeMap);
+                
+                // Check the initial value of the variable.
+                LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
+                containedConstants = variable.getInitialValueExpression().getConstants();
+                isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
+                variable.getInitialValueExpression().check(identifierToTypeMap);
+                
+                // Register the type of the constant for later type checks.
+                identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Int);
+
+                // Record the new identifier for future checks.
+                variableNames.insert(variable.getName());
+                allIdentifiers.insert(variable.getName());
+            }
+
+            // Now go through the variables of the modules.
+            for (auto const& module : this->getModules()) {
+                for (auto const& variable : module.getBooleanVariables()) {
+                    // Check for duplicate identifiers.
+                    LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
+                    
+                    // Check the initial value of the variable.
+                    LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
+                    std::set<std::string> containedConstants = variable.getInitialValueExpression().getConstants();
+                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
+                    variable.getInitialValueExpression().check(identifierToTypeMap);
+                    
+                    // Register the type of the constant for later type checks.
+                    identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Bool);
+                    
+                    // Record the new identifier for future checks.
+                    variableNames.insert(variable.getName());
+                    allIdentifiers.insert(variable.getName());
+                }
+                for (auto const& variable : module.getIntegerVariables()) {
+                    // Check for duplicate identifiers.
+                    LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
+                    
+                    // Register the type of the constant for later type checks.
+                    identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Int);
+                    
+                    // Check that bound expressions of the range.
+                    LOG_THROW(variable.getLowerBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression must not refer to variables.");
+                    std::set<std::string> containedConstants = variable.getLowerBoundExpression().getConstants();
+                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression refers to unknown constants.");
+                    variable.getLowerBoundExpression().check(identifierToTypeMap);
+                    LOG_THROW(variable.getUpperBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression must not refer to variables.");
+                    containedConstants = variable.getLowerBoundExpression().getConstants();
+                    isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants.");
+                    variable.getUpperBoundExpression().check(identifierToTypeMap);
+                    
+                    // Check the initial value of the variable.
+                    LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
+                    containedConstants = variable.getInitialValueExpression().getConstants();
+                    isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
+                    variable.getInitialValueExpression().check(identifierToTypeMap);
+                    
+                    // Record the new identifier for future checks.
+                    variableNames.insert(variable.getName());
+                    allIdentifiers.insert(variable.getName());
+                }
+            }
+            
+            // Create the set of valid identifiers for future checks.
+            std::set<std::string> variablesAndConstants;
+            std::set_union(variableNames.begin(), variableNames.end(), constantNames.begin(), constantNames.end(), std::inserter(variablesAndConstants, variablesAndConstants.begin()));
+            
+            // TODO: check commands.
+            
+            // TODO: check reward models.
+            
+            // Check the initial states expression (if the program defines it).
+            if (this->hasInitialStatesExpression) {
+                std::set<std::string> containedIdentifiers = this->initialStatesExpression.getIdentifiers();
+                bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << this->getFilename() << ", line " << this->getLineNumber() << ": initial expression refers to unknown identifiers.");
+                this->initialStatesExpression.check(identifierToTypeMap);
+            }
+            
+            // Check the labels.
+            for (auto const& label : this->getLabels()) {
+                // Check for duplicate identifiers.
+                LOG_THROW(allIdentifiers.find(label.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": duplicate identifier '" << label.getName() << "'.");
+                
+                std::set<std::string> containedIdentifiers = label.getStatePredicateExpression().getIdentifiers();
+                bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": label expression refers to unknown identifiers.");
+                label.getStatePredicateExpression().check(identifierToTypeMap);
+            }
+            
+            // Check the formulas.
+            for (auto const& formula : this->getFormulas()) {
+                // Check for duplicate identifiers.
+                LOG_THROW(allIdentifiers.find(formula.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << formula.getFilename() << ", line " << formula.getLineNumber() << ": duplicate identifier '" << formula.getName() << "'.");
+                
+                std::set<std::string> containedIdentifiers = formula.getExpression().getIdentifiers();
+                bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << formula.getFilename() << ", line " << formula.getLineNumber() << ": formula expression refers to unknown identifiers.");
+                formula.getExpression().check(identifierToTypeMap);
+                
+                // Record the new identifier for future checks.
+                allIdentifiers.insert(formula.getName());
+            }
+        }
+        
         std::ostream& operator<<(std::ostream& stream, Program const& program) {
             switch (program.getModelType()) {
                 case Program::ModelType::UNDEFINED: stream << "undefined"; break;
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 40f8047e1..b1b387427 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -285,6 +285,12 @@ namespace storm {
              */
             Program substituteConstants() const;
             
+            /*!
+             * Checks the validity of the program. If the program is not valid, an exception is thrown with a message
+             * that indicates the source of the problem.
+             */
+            void checkValidity() const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Program const& program);
             
         private:

From c76e0e8d4d63be0f7371807bd5e15499fd809c39 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 5 May 2014 14:41:17 +0200
Subject: [PATCH 101/147] Added class for initial construct of PRISM programs
 (to capture position information). Added more validity checks for programs
 and tests for them (not all though).

Former-commit-id: cf4e985684a225d4f99e9ad58d7737cd67409e3e
---
 src/parser/PrismParser.cpp                    |  38 +--
 src/parser/PrismParser.h                      |  16 +-
 src/storage/expressions/BaseExpression.cpp    |   7 +-
 .../expressions/SubstitutionVisitor.cpp       |   4 +-
 src/storage/expressions/TypeCheckVisitor.cpp  |  12 +-
 src/storage/prism/Command.cpp                 |   2 +-
 src/storage/prism/Constant.cpp                |   4 +-
 src/storage/prism/Formula.cpp                 |   4 +-
 src/storage/prism/InitialConstruct.cpp        |  24 ++
 src/storage/prism/InitialConstruct.h          |  56 ++++
 src/storage/prism/Label.cpp                   |   4 +-
 src/storage/prism/LocatedInformation.cpp      |   4 +-
 src/storage/prism/Module.cpp                  |   3 +-
 src/storage/prism/Program.cpp                 | 265 ++++++++++++++----
 src/storage/prism/Program.h                   |  35 +--
 src/storage/prism/Update.cpp                  |   2 +-
 test/functional/parser/PrismParserTest.cpp    | 184 ++++++------
 17 files changed, 442 insertions(+), 222 deletions(-)
 create mode 100644 src/storage/prism/InitialConstruct.cpp
 create mode 100644 src/storage/prism/InitialConstruct.h

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index ffda5e219..727579dff 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -5,7 +5,7 @@
 
 namespace storm {
     namespace parser {
-        storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) {
+        storm::prism::Program PrismParser::parse(std::string const& filename) {
             // Open file and initialize result.
             std::ifstream inputFileStream(filename, std::ios::in);
             LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
@@ -15,7 +15,7 @@ namespace storm {
             // Now try to parse the contents of the file.
             try {
                 std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
-                result = parseFromString(fileContent, filename, typeCheck);
+                result = parseFromString(fileContent, filename);
             } catch(std::exception& e) {
                 // In case of an exception properly close the file before passing exception.
                 inputFileStream.close();
@@ -27,7 +27,7 @@ namespace storm {
             return result;
         }
         
-        storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool typeCheck) {
+        storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename) {
             PositionIteratorType first(input.begin());
             PositionIteratorType iter = first;
             PositionIteratorType last(input.end());
@@ -38,17 +38,17 @@ namespace storm {
             // Create grammar.
             storm::parser::PrismParser grammar(filename, first);
             try {
-                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
+                // Start first run.
                 bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
                 LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in first pass.");
-                if (typeCheck) {
-                    first = PositionIteratorType(input.begin());
-                    iter = first;
-                    last = PositionIteratorType(input.end());
-                    grammar.moveToSecondRun();
-                    succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
-                    LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in second pass.");
-                }
+                
+                // Start second run.
+                first = PositionIteratorType(input.begin());
+                iter = first;
+                last = PositionIteratorType(input.end());
+                grammar.moveToSecondRun();
+                succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
+                LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in second pass.");
             } catch (qi::expectation_failure<PositionIteratorType> const& e) {
                 // If the parser expected content different than the one provided, display information about the location of the error.
                 std::size_t lineNumber = boost::spirit::get_line(e.first);
@@ -162,7 +162,7 @@ namespace storm {
                                      >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismParser::createRewardModel, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
             rewardModelDefinition.name("reward model definition");
             
-            initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)];
+            initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesConstruct, phoenix::ref(*this), qi::_1, qi::_r1)];
             initialStatesConstruct.name("initial construct");
             
             labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
@@ -264,13 +264,13 @@ namespace storm {
             return true;
         }
         
-        bool PrismParser::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
-            LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Program must not define two initial constructs.");
-            if (globalProgramInformation.hasInitialStatesExpression) {
+        bool PrismParser::addInitialStatesConstruct(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
+            LOG_THROW(!globalProgramInformation.hasInitialConstruct, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Program must not define two initial constructs.");
+            if (globalProgramInformation.hasInitialConstruct) {
                 return false;
             }
-            globalProgramInformation.hasInitialStatesExpression = true;
-            globalProgramInformation.initialStatesExpression = initialStatesExpression;
+            globalProgramInformation.hasInitialConstruct = true;
+            globalProgramInformation.initialConstruct = storm::prism::InitialConstruct(initialStatesExpression, this->getFilename(), get_line(qi::_3));
             return true;
         }
         
@@ -762,7 +762,7 @@ namespace storm {
         }
         
         storm::prism::Program PrismParser::createProgram(GlobalProgramInformation const& globalProgramInformation) const {
-            return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, globalProgramInformation.hasInitialStatesExpression, globalProgramInformation.initialStatesExpression, globalProgramInformation.labels, this->getFilename());
+            return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, this->secondRun && !globalProgramInformation.hasInitialConstruct, globalProgramInformation.initialConstruct, globalProgramInformation.labels, this->getFilename(), 1, this->secondRun);
         }
     } // namespace parser
 } // namespace storm
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 3312768c3..e1a9136ba 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -35,7 +35,9 @@ namespace storm {
         class GlobalProgramInformation {
         public:
             // Default construct the header information.
-			GlobalProgramInformation() : hasInitialStatesExpression(false), currentCommandIndex(0), currentUpdateIndex(0) {}
+			GlobalProgramInformation() : modelType(), constants(), formulas(), globalBooleanVariables(), globalIntegerVariables(), moduleToIndexMap(), modules(), rewardModels(), labels(),hasInitialConstruct(false), initialConstruct(storm::expressions::Expression::createFalse()), currentCommandIndex(0), currentUpdateIndex(0) {
+                // Intentionally left empty.
+            }
             
             // Members for all essential information that needs to be collected.
             storm::prism::Program::ModelType modelType;
@@ -47,8 +49,8 @@ namespace storm {
             std::vector<storm::prism::Module> modules;
             std::vector<storm::prism::RewardModel> rewardModels;
             std::vector<storm::prism::Label> labels;
-            storm::expressions::Expression initialStatesExpression;
-            bool hasInitialStatesExpression;
+            bool hasInitialConstruct;
+            storm::prism::InitialConstruct initialConstruct;
             
             // Counters to provide unique indexing for commands and updates.
             uint_fast64_t currentCommandIndex;
@@ -61,20 +63,18 @@ namespace storm {
              * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
              *
              * @param filename the name of the file to parse.
-             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
              * @return The resulting PRISM program.
              */
-            static storm::prism::Program parse(std::string const& filename, bool typeCheck = true);
+            static storm::prism::Program parse(std::string const& filename);
             
             /*!
              * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
              *
              * @param input The input string to parse.
              * @param filename The name of the file from which the input was read.
-             * @param typeCheck Sets whether the expressions are generated and therefore typechecked.
              * @return The resulting PRISM program.
              */
-            static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool typeCheck = true);
+            static storm::prism::Program parseFromString(std::string const& input, std::string const& filename);
             
         private:
             struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
@@ -263,7 +263,7 @@ namespace storm {
             
             // Helper methods used in the grammar.
             bool isValidIdentifier(std::string const& identifier);
-            bool addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
+            bool addInitialStatesConstruct(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
             
             storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const;
             storm::expressions::Expression createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index b9734a9ad..bb4ea0921 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -53,7 +53,12 @@ namespace storm {
         }
         
         std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue) {
-            stream << static_cast<std::underlying_type<ExpressionReturnType>::type>(enumValue);
+            switch (enumValue) {
+                case ExpressionReturnType::Undefined: stream << "undefined"; break;
+                case ExpressionReturnType::Bool: stream << "bool"; break;
+                case ExpressionReturnType::Int: stream << "int"; break;
+                case ExpressionReturnType::Double: stream << "double"; break;
+            }
             return stream;
         }
         
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index 402febc2e..7990ab4f9 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -182,7 +182,7 @@ namespace storm {
         }
         
         // Explicitly instantiate the class with map and unordered_map.
-		template class SubstitutionVisitor< std::map<std::string, Expression> >;
-		template class SubstitutionVisitor< std::unordered_map<std::string, Expression> >;
+		template class SubstitutionVisitor<std::map<std::string, Expression>>;
+		template class SubstitutionVisitor<std::unordered_map<std::string, Expression>>;
     }
 }
diff --git a/src/storage/expressions/TypeCheckVisitor.cpp b/src/storage/expressions/TypeCheckVisitor.cpp
index b1cd6a205..d5cef0381 100644
--- a/src/storage/expressions/TypeCheckVisitor.cpp
+++ b/src/storage/expressions/TypeCheckVisitor.cpp
@@ -45,28 +45,28 @@ namespace storm {
         void TypeCheckVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
             auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
             LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected bool, but found " << expression->getReturnType() << ".");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected 'bool', but found '" << expression->getReturnType() << "'.");
         }
         
         template<typename MapType>
         void TypeCheckVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
             auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
             LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected double, but found " << expression->getReturnType() << ".");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Double, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected 'double', but found '" << expression->getReturnType() << "'.");
         }
         
         template<typename MapType>
         void TypeCheckVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
             auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
             LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected int, but found " << expression->getReturnType() << ".");
+            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Int, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected 'int', but found '" << expression->getReturnType() << "'.");
         }
         
         template<typename MapType>
         void TypeCheckVisitor<MapType>::visit(VariableExpression const* expression) {
             auto identifierTypePair = this->identifierToTypeMap.find(expression->getVariableName());
             LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getVariableName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for variable '" << expression->getVariableName() << "': expected " << identifierTypePair->first << ", but found " << expression->getReturnType() << ".");
+            LOG_THROW(identifierTypePair->second == expression->getReturnType(), storm::exceptions::InvalidTypeException, "Type mismatch for variable '" << expression->getVariableName() << "': expected '" << identifierTypePair->first << "', but found '" << expression->getReturnType() << "'.");
         }
         
         template<typename MapType>
@@ -93,5 +93,9 @@ namespace storm {
         void TypeCheckVisitor<MapType>::visit(DoubleLiteralExpression const* expression) {
             // Intentionally left empty.
         }
+        
+        // Explicitly instantiate the class with map and unordered_map.
+		template class TypeCheckVisitor<std::map<std::string, ExpressionReturnType>>;
+		template class TypeCheckVisitor<std::unordered_map<std::string, ExpressionReturnType>>;
     }
 }
\ No newline at end of file
diff --git a/src/storage/prism/Command.cpp b/src/storage/prism/Command.cpp
index 4b36942df..4c1619732 100644
--- a/src/storage/prism/Command.cpp
+++ b/src/storage/prism/Command.cpp
@@ -51,5 +51,5 @@ namespace storm {
             stream << ";";
             return stream;
         }
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 641336c76..c02deea99 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -48,5 +48,5 @@ namespace storm {
             stream << ";";
             return stream;
         }
-    }
-}
\ No newline at end of file
+    } // namespace prism
+} // namespace storm
\ No newline at end of file
diff --git a/src/storage/prism/Formula.cpp b/src/storage/prism/Formula.cpp
index fbda0c69d..a120078b8 100644
--- a/src/storage/prism/Formula.cpp
+++ b/src/storage/prism/Formula.cpp
@@ -26,5 +26,5 @@ namespace storm {
             stream << "formula " << formula.getName() << " = " << formula.getExpression() << ";";
             return stream;
         }
-    }
-}
\ No newline at end of file
+    } // namespace prism
+} // namespace storm
\ No newline at end of file
diff --git a/src/storage/prism/InitialConstruct.cpp b/src/storage/prism/InitialConstruct.cpp
new file mode 100644
index 000000000..61c662843
--- /dev/null
+++ b/src/storage/prism/InitialConstruct.cpp
@@ -0,0 +1,24 @@
+#include "src/storage/prism/InitialConstruct.h"
+
+namespace storm {
+    namespace prism {
+        InitialConstruct::InitialConstruct(storm::expressions::Expression initialStatesExpression, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), initialStatesExpression(initialStatesExpression) {
+            // Intentionally left empty.
+        }
+        
+        storm::expressions::Expression InitialConstruct::getInitialStatesExpression() const {
+            return this->initialStatesExpression;
+        }
+        
+        InitialConstruct InitialConstruct::substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const {
+            return InitialConstruct(this->getInitialStatesExpression().substitute(substitution));
+        }
+        
+        std::ostream& operator<<(std::ostream& stream, InitialConstruct const& initialConstruct) {
+            stream << "initial " << std::endl;
+            stream << "\t" << initialConstruct.getInitialStatesExpression() << std::endl;
+            stream << "endinitial" << std::endl;
+            return stream;
+        }
+    } // namespace prism
+} // namespace storm
\ No newline at end of file
diff --git a/src/storage/prism/InitialConstruct.h b/src/storage/prism/InitialConstruct.h
new file mode 100644
index 000000000..6f7f6adb9
--- /dev/null
+++ b/src/storage/prism/InitialConstruct.h
@@ -0,0 +1,56 @@
+#ifndef STORM_STORAGE_PRISM_INITIALCONSTRUCT_H_
+#define STORM_STORAGE_PRISM_INITIALCONSTRUCT_H_
+
+#include <string>
+
+#include "src/storage/prism/LocatedInformation.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/utility/OsDetection.h"
+
+namespace storm {
+    namespace prism {
+        class InitialConstruct : public LocatedInformation {
+            public:
+            /*!
+             * Creates an initial construct with the given expression.
+             *
+             * @param initialStatesExpression An expression characterizing the initial states.
+             * @param filename The filename in which the command is defined.
+             * @param lineNumber The line number in which the command is defined.
+             */
+            InitialConstruct(storm::expressions::Expression initialStatesExpression, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            
+            // Create default implementations of constructors/assignment.
+            InitialConstruct() = default;
+            InitialConstruct(InitialConstruct const& other) = default;
+            InitialConstruct& operator=(InitialConstruct const& other)= default;
+#ifndef WINDOWS
+            InitialConstruct(InitialConstruct&& other) = default;
+            InitialConstruct& operator=(InitialConstruct&& other) = default;
+#endif
+            
+            /*!
+             * Retrieves the expression characterizing the initial states.
+             *
+             * @return The expression characterizing the initial states.
+             */
+            storm::expressions::Expression getInitialStatesExpression() const;
+            
+            /*!
+             * Substitutes all identifiers in the constant according to the given map.
+             *
+             * @param substitution The substitution to perform.
+             * @return The resulting initial construct.
+             */
+            InitialConstruct substitute(std::map<std::string, storm::expressions::Expression> const& substitution) const;
+            
+            friend std::ostream& operator<<(std::ostream& stream, InitialConstruct const& initialConstruct);
+            
+        private:
+            // An expression characterizing the initial states.
+            storm::expressions::Expression initialStatesExpression;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_PRISM_INITIALCONSTRUCT_H_ */
\ No newline at end of file
diff --git a/src/storage/prism/Label.cpp b/src/storage/prism/Label.cpp
index cb8a13f25..d11091cf0 100644
--- a/src/storage/prism/Label.cpp
+++ b/src/storage/prism/Label.cpp
@@ -22,5 +22,5 @@ namespace storm {
             stream << "label \"" << label.getName() << "\" = " << label.getStatePredicateExpression() << ";";
             return stream;
         }
-    }
-}
\ No newline at end of file
+    } // namespace prism
+} // namespace storm
\ No newline at end of file
diff --git a/src/storage/prism/LocatedInformation.cpp b/src/storage/prism/LocatedInformation.cpp
index a5a493319..a3862d57a 100644
--- a/src/storage/prism/LocatedInformation.cpp
+++ b/src/storage/prism/LocatedInformation.cpp
@@ -21,5 +21,5 @@ namespace storm {
         void LocatedInformation::setLineNumber(uint_fast64_t lineNumber) {
             this->lineNumber = lineNumber;
         }
-    }
-}
\ No newline at end of file
+    } // namespace prism
+} // namespace storm
\ No newline at end of file
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index d7b3fb572..6f4becb0a 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -182,7 +182,6 @@ namespace storm {
             stream << "endmodule" << std::endl;
             return stream;
         }
-
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 5e024cd53..c29001b16 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -6,13 +6,41 @@
 #include "exceptions/InvalidArgumentException.h"
 #include "src/exceptions/OutOfRangeException.h"
 #include "src/exceptions/WrongFormatException.h"
+#include "src/exceptions/InvalidTypeException.h"
 
 namespace storm {
     namespace prism {
-        Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), constantToIndexMap(), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), hasInitialStatesExpression(hasInitialStatesExpression), initialStatesExpression(initialStatesExpression), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
+        Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool fixInitialConstruct, storm::prism::InitialConstruct const& initialConstruct, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber, bool checkValidity) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), constantToIndexMap(), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), initialConstruct(initialConstruct), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
             this->createMappings();
+            
+            // Create a new initial construct if none was given explicitly.
+            if (fixInitialConstruct) {
+                if (this->getInitialConstruct().getInitialStatesExpression().isFalse()) {
+                    storm::expressions::Expression newInitialExpression = storm::expressions::Expression::createTrue();
+                    
+                    for (auto const& booleanVariable : this->getGlobalBooleanVariables()) {
+                        newInitialExpression = newInitialExpression && (storm::expressions::Expression::createBooleanVariable(booleanVariable.getName()).iff(booleanVariable.getInitialValueExpression()));
+                    }
+                    for (auto const& integerVariable : this->getGlobalIntegerVariables()) {
+                        newInitialExpression = newInitialExpression && (storm::expressions::Expression::createIntegerVariable(integerVariable.getName()) == integerVariable.getInitialValueExpression());
+                    }
+                    for (auto const& module : this->getModules()) {
+                        for (auto const& booleanVariable : module.getBooleanVariables()) {
+                            newInitialExpression = newInitialExpression && (storm::expressions::Expression::createBooleanVariable(booleanVariable.getName()).iff(booleanVariable.getInitialValueExpression()));
+                        }
+                        for (auto const& integerVariable : module.getIntegerVariables()) {
+                            newInitialExpression = newInitialExpression && (storm::expressions::Expression::createIntegerVariable(integerVariable.getName()) == integerVariable.getInitialValueExpression());
+                        }
+                    }
+                    this->initialConstruct = storm::prism::InitialConstruct(newInitialExpression, this->getInitialConstruct().getFilename(), this->getInitialConstruct().getLineNumber());
+                }
+            }
+            
+            if (checkValidity) {
+                this->checkValidity();
+            }
         }
-        
+    
         Program::ModelType Program::getModelType() const {
             return modelType;
         }
@@ -97,28 +125,8 @@ namespace storm {
             return this->modules;
         }
         
-        bool Program::definesInitialStatesExpression() const {
-            return this->hasInitialStatesExpression;
-        }
-        
-        storm::expressions::Expression Program::getInitialStatesExpression() const {
-            // If the program specifies the initial states explicitly, we simply return the expression.
-            if (this->definesInitialStatesExpression()) {
-                return this->initialStatesExpression;
-            } else {
-                // Otherwise, we need to assert that all variables are equal to their initial value.
-                storm::expressions::Expression result = storm::expressions::Expression::createTrue();
-                
-                for (auto const& module : this->getModules()) {
-                    for (auto const& booleanVariable : module.getBooleanVariables()) {
-                        result = result && (storm::expressions::Expression::createBooleanVariable(booleanVariable.getName()).iff(booleanVariable.getInitialValueExpression()));
-                    }
-                    for (auto const& integerVariable : module.getIntegerVariables()) {
-                        result = result && (storm::expressions::Expression::createIntegerVariable(integerVariable.getName()) == integerVariable.getInitialValueExpression());
-                    }
-                }
-                return result;
-            }
+        storm::prism::InitialConstruct const& Program::getInitialConstruct() const {
+            return this->initialConstruct;
         }
         
         std::set<std::string> const& Program::getActions() const {
@@ -167,7 +175,7 @@ namespace storm {
                 newModules.push_back(module.restrictCommands(indexSet));
             }
             
-            return Program(this->getModelType(), this->getConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+            return Program(this->getModelType(), this->getConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getRewardModels(), false, this->getInitialConstruct(), this->getLabels());
         }
         
         void Program::createMappings() {
@@ -259,7 +267,7 @@ namespace storm {
                 LOG_THROW(definedUndefinedConstants.find(constantExpressionPair.first) != definedUndefinedConstants.end(), storm::exceptions::InvalidArgumentException, "Unable to define non-existant constant.");
             }
             
-            return Program(this->getModelType(), newConstants, this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), this->getModules(), this->getRewardModels(), this->definesInitialStatesExpression(), this->getInitialStatesExpression(), this->getLabels());
+            return Program(this->getModelType(), newConstants, this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), this->getModules(), this->getRewardModels(), false, this->getInitialConstruct(), this->getLabels());
         }
         
         Program Program::substituteConstants() const {
@@ -310,7 +318,7 @@ namespace storm {
                 newRewardModels.emplace_back(rewardModel.substitute(constantSubstitution));
             }
             
-            storm::expressions::Expression newInitialStateExpression = this->getInitialStatesExpression().substitute(constantSubstitution);
+            storm::prism::InitialConstruct newInitialConstruct = this->getInitialConstruct().substitute(constantSubstitution);
             
             std::vector<Label> newLabels;
             newLabels.reserve(this->getNumberOfLabels());
@@ -318,7 +326,7 @@ namespace storm {
                 newLabels.emplace_back(label.substitute(constantSubstitution));
             }
             
-            return Program(this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, this->definesInitialStatesExpression(), newInitialStateExpression, newLabels);
+            return Program(this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, newRewardModels, false, newInitialConstruct, newLabels);
         }
         
         void Program::checkValidity() const {
@@ -327,6 +335,7 @@ namespace storm {
             
             // Start by checking the constant declarations.
             std::set<std::string> allIdentifiers;
+            std::set<std::string> globalIdentifiers;
             std::set<std::string> constantNames;
             for (auto const& constant : this->getConstants()) {
                 // Check for duplicate identifiers.
@@ -340,9 +349,12 @@ namespace storm {
                     bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstantNames.begin(), containedConstantNames.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": defining expression refers to unknown constants.");
                     
-                    // Now check that the constants appear with the right types (this throws an exception if this is not
-                    // the case).
-                    constant.getExpression().check(identifierToTypeMap);
+                    // Now check that the constants appear with the right types.
+                    try {
+                        constant.getExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": " << e.what());
+                    }
                 }
                 
                 // Finally, register the type of the constant for later type checks.
@@ -351,6 +363,7 @@ namespace storm {
                 // Record the new identifier for future checks.
                 constantNames.insert(constant.getName());
                 allIdentifiers.insert(constant.getName());
+                globalIdentifiers.insert(constant.getName());
             }
             
             // Now we check the variable declarations. We start with the global variables.
@@ -364,7 +377,11 @@ namespace storm {
                 std::set<std::string> containedConstants = variable.getInitialValueExpression().getConstants();
                 bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
+                try {
                 variable.getInitialValueExpression().check(identifierToTypeMap);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                }
 
                 // Register the type of the constant for later type checks.
                 identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Bool);
@@ -372,6 +389,7 @@ namespace storm {
                 // Record the new identifier for future checks.
                 variableNames.insert(variable.getName());
                 allIdentifiers.insert(variable.getName());
+                globalIdentifiers.insert(variable.getName());
             }
             for (auto const& variable : this->getGlobalIntegerVariables()) {
                 // Check for duplicate identifiers.
@@ -382,19 +400,32 @@ namespace storm {
                 std::set<std::string> containedConstants = variable.getLowerBoundExpression().getConstants();
                 bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression refers to unknown constants.");
-                variable.getLowerBoundExpression().check(identifierToTypeMap);
+                try {
+                    variable.getLowerBoundExpression().check(identifierToTypeMap);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                }
+
                 LOG_THROW(variable.getUpperBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression must not refer to variables.");
                 containedConstants = variable.getLowerBoundExpression().getConstants();
                 isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants.");
-                variable.getUpperBoundExpression().check(identifierToTypeMap);
+                try {
+                    variable.getUpperBoundExpression().check(identifierToTypeMap);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                }
                 
                 // Check the initial value of the variable.
                 LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
                 containedConstants = variable.getInitialValueExpression().getConstants();
                 isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
-                variable.getInitialValueExpression().check(identifierToTypeMap);
+                try {
+                    variable.getInitialValueExpression().check(identifierToTypeMap);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                }
                 
                 // Register the type of the constant for later type checks.
                 identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Int);
@@ -402,6 +433,7 @@ namespace storm {
                 // Record the new identifier for future checks.
                 variableNames.insert(variable.getName());
                 allIdentifiers.insert(variable.getName());
+                globalIdentifiers.insert(variable.getName());
             }
 
             // Now go through the variables of the modules.
@@ -415,7 +447,11 @@ namespace storm {
                     std::set<std::string> containedConstants = variable.getInitialValueExpression().getConstants();
                     bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
-                    variable.getInitialValueExpression().check(identifierToTypeMap);
+                    try {
+                        variable.getInitialValueExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                    }
                     
                     // Register the type of the constant for later type checks.
                     identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Bool);
@@ -436,19 +472,32 @@ namespace storm {
                     std::set<std::string> containedConstants = variable.getLowerBoundExpression().getConstants();
                     bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression refers to unknown constants.");
-                    variable.getLowerBoundExpression().check(identifierToTypeMap);
+                    try {
+                        variable.getLowerBoundExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                    }
+
                     LOG_THROW(variable.getUpperBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression must not refer to variables.");
                     containedConstants = variable.getLowerBoundExpression().getConstants();
                     isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants.");
-                    variable.getUpperBoundExpression().check(identifierToTypeMap);
+                    try {
+                        variable.getUpperBoundExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                    }
                     
                     // Check the initial value of the variable.
                     LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
                     containedConstants = variable.getInitialValueExpression().getConstants();
                     isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
-                    variable.getInitialValueExpression().check(identifierToTypeMap);
+                    try {
+                        variable.getInitialValueExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
+                    }
                     
                     // Record the new identifier for future checks.
                     variableNames.insert(variable.getName());
@@ -460,16 +509,124 @@ namespace storm {
             std::set<std::string> variablesAndConstants;
             std::set_union(variableNames.begin(), variableNames.end(), constantNames.begin(), constantNames.end(), std::inserter(variablesAndConstants, variablesAndConstants.begin()));
             
-            // TODO: check commands.
+            // Check the commands of the modules.
+            for (auto const& module : this->getModules()) {
+                std::set<std::string> legalIdentifiers = globalIdentifiers;
+                for (auto const& variable : module.getBooleanVariables()) {
+                    legalIdentifiers.insert(variable.getName());
+                }
+                for (auto const& variable : module.getIntegerVariables()) {
+                    legalIdentifiers.insert(variable.getName());
+                }
+                
+                for (auto const& command : module.getCommands()) {
+                    // Check the guard.
+                    std::set<std::string> containedIdentifiers = command.getGuardExpression().getIdentifiers();
+                    bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": guard refers to unknown identifiers.");
+                    try {
+                        command.getGuardExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": " << e.what());
+                    }
+                    LOG_THROW(command.getGuardExpression().hasBooleanReturnType(), storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": expression for guard must evaluate to type 'bool'.");
+                    
+                    // Check all updates.
+                    for (auto const& update : command.getUpdates()) {
+                        containedIdentifiers = update.getLikelihoodExpression().getIdentifiers();
+                        isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                        LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": likelihood expression refers to unknown identifiers.");
+                        try {
+                            update.getLikelihoodExpression().check(identifierToTypeMap);
+                        } catch (storm::exceptions::InvalidTypeException const& e) {
+                            LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": " << e.what());
+                        }
+                        
+                        // Check all assignments.
+                        std::set<std::string> alreadyAssignedIdentifiers;
+                        for (auto const& assignment : update.getAssignments()) {
+                            if (legalIdentifiers.find(assignment.getVariableName()) == legalIdentifiers.end()) {
+                                if (allIdentifiers.find(assignment.getVariableName()) != allIdentifiers.end()) {
+                                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": assignment illegally refers to variable '" << assignment.getVariableName() << "'.");
+                                } else {
+                                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": assignment refers to unknown variable '" << assignment.getVariableName() << "'.");
+                                }
+                            }
+                            LOG_THROW(alreadyAssignedIdentifiers.find(assignment.getVariableName()) == alreadyAssignedIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": duplicate assignment to variable '" << assignment.getVariableName() << "'.");
+                            auto variableTypePair = identifierToTypeMap.find(assignment.getVariableName());
+                            LOG_THROW(variableTypePair->second == assignment.getExpression().getReturnType(), storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": illegally assigning a value of type '" << assignment.getExpression().getReturnType() << "' to variable '" << variableTypePair->first << "' of type '" << variableTypePair->second << "'.");
+                            
+                            containedIdentifiers = assignment.getExpression().getIdentifiers();
+                            isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                            LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": likelihood expression refers to unknown identifiers.");
+                            try {
+                                assignment.getExpression().check(identifierToTypeMap);
+                            } catch (storm::exceptions::InvalidTypeException const& e) {
+                                LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": " << e.what());
+                            }
+                            
+                            // Add the current variable to the set of assigned variables (of this update).
+                            alreadyAssignedIdentifiers.insert(assignment.getVariableName());
+                        }
+                    }
+                }
+            }
             
-            // TODO: check reward models.
+            // Now check the reward models.
+            for (auto const& rewardModel : this->getRewardModels()) {
+                for (auto const& stateReward : rewardModel.getStateRewards()) {
+                    std::set<std::string> containedIdentifiers = stateReward.getStatePredicateExpression().getIdentifiers();
+                    bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": state reward expression refers to unknown identifiers.");
+                    try {
+                        stateReward.getStatePredicateExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": " << e.what());
+                    }
+                    LOG_THROW(stateReward.getStatePredicateExpression().hasBooleanReturnType(), storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": state predicate must evaluate to type 'bool'.");
+                    
+                    containedIdentifiers = stateReward.getRewardValueExpression().getIdentifiers();
+                    isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": state reward value expression refers to unknown identifiers.");
+                    try {
+                        stateReward.getRewardValueExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": " << e.what());
+                    }
+                    LOG_THROW(stateReward.getRewardValueExpression().hasNumericalReturnType(), storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": reward value expression must evaluate to numerical type.");
+                }
+                
+                for (auto const& transitionReward : rewardModel.getTransitionRewards()) {
+                    std::set<std::string> containedIdentifiers = transitionReward.getStatePredicateExpression().getIdentifiers();
+                    bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": state reward expression refers to unknown identifiers.");
+                    try {
+                        transitionReward.getStatePredicateExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": " << e.what());
+                    }
+                    LOG_THROW(transitionReward.getStatePredicateExpression().hasBooleanReturnType(), storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": state predicate must evaluate to type 'bool'.");
+                    
+                    containedIdentifiers = transitionReward.getRewardValueExpression().getIdentifiers();
+                    isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": state reward value expression refers to unknown identifiers.");
+                    try {
+                        transitionReward.getRewardValueExpression().check(identifierToTypeMap);
+                    } catch (storm::exceptions::InvalidTypeException const& e) {
+                        LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": " << e.what());
+                    }
+                    LOG_THROW(transitionReward.getRewardValueExpression().hasNumericalReturnType(), storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": reward value expression must evaluate to numerical type.");
+                }
+            }
             
-            // Check the initial states expression (if the program defines it).
-            if (this->hasInitialStatesExpression) {
-                std::set<std::string> containedIdentifiers = this->initialStatesExpression.getIdentifiers();
-                bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
-                LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << this->getFilename() << ", line " << this->getLineNumber() << ": initial expression refers to unknown identifiers.");
-                this->initialStatesExpression.check(identifierToTypeMap);
+            // Check the initial states expression.
+            std::set<std::string> containedIdentifiers = this->getInitialConstruct().getInitialStatesExpression().getIdentifiers();
+            bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+            LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << this->getInitialConstruct().getFilename() << ", line " << this->getInitialConstruct().getLineNumber() << ": initial expression refers to unknown identifiers.");
+            try {
+                this->getInitialConstruct().getInitialStatesExpression().check(identifierToTypeMap);
+            } catch (storm::exceptions::InvalidTypeException const& e) {
+                LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << this->getInitialConstruct().getFilename() << ", line " << this->getInitialConstruct().getLineNumber() << ": " << e.what());
             }
             
             // Check the labels.
@@ -480,7 +637,13 @@ namespace storm {
                 std::set<std::string> containedIdentifiers = label.getStatePredicateExpression().getIdentifiers();
                 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": label expression refers to unknown identifiers.");
-                label.getStatePredicateExpression().check(identifierToTypeMap);
+                try {
+                    label.getStatePredicateExpression().check(identifierToTypeMap);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": " << e.what());
+                }
+                
+                LOG_THROW(label.getStatePredicateExpression().hasBooleanReturnType(), storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": label predicate must evaluate to type 'bool'.");
             }
             
             // Check the formulas.
@@ -491,7 +654,11 @@ namespace storm {
                 std::set<std::string> containedIdentifiers = formula.getExpression().getIdentifiers();
                 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << formula.getFilename() << ", line " << formula.getLineNumber() << ": formula expression refers to unknown identifiers.");
-                formula.getExpression().check(identifierToTypeMap);
+                try {
+                    formula.getExpression().check(identifierToTypeMap);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << formula.getFilename() << ", line " << formula.getLineNumber() << ": " << e.what());
+                }
                 
                 // Record the new identifier for future checks.
                 allIdentifiers.insert(formula.getName());
@@ -542,5 +709,5 @@ namespace storm {
             return stream;
         }
         
-    } // namespace ir
+    } // namespace prism
 } // namepsace storm
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index b1b387427..2a618ff7a 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -12,6 +12,7 @@
 #include "src/storage/prism/Label.h"
 #include "src/storage/prism/Module.h"
 #include "src/storage/prism/RewardModel.h"
+#include "src/storage/prism/InitialConstruct.h"
 #include "src/utility/OsDetection.h"
 
 namespace storm {
@@ -33,17 +34,18 @@ namespace storm {
              * @param globalIntegerVariables The global integer variables of the program.
              * @param formulas The formulas defined in the program.
              * @param modules The modules of the program.
-             * @param hasInitialStatesExpression A flag indicating whether the program specifies its initial states via
-             * an explicit initial construct.
-             * @param initialStatesExpression If the model specifies an explicit initial construct, this
-             * expression defines its initial states. Otherwise it is irrelevant and may be set to an arbitrary (but
-             * valid) expression, e.g. false.
+             * @param fixInitialConstruct A flag that indicates whether the given initial construct is to be ignored and
+             * replaced by a new one created from the initial values of the variables.
+             * @param initialConstruct The initial construct of the program. If the initial construct specifies "false"
+             * as the initial condition, the default values of the variables are used to construct a legal initial
+             * condition.
              * @param rewardModels The reward models of the program.
              * @param labels The labels defined for this program.
              * @param filename The filename in which the program is defined.
              * @param lineNumber The line number in which the program is defined.
+             * @param checkValidity If set to true, the program is checked for validity.
              */
-            Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool hasInitialStatesExpression, storm::expressions::Expression const& initialStatesExpression, std::vector<Label> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0);
+            Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool fixInitialConstruct, storm::prism::InitialConstruct const& initialConstruct, std::vector<Label> const& labels, std::string const& filename = "", uint_fast64_t lineNumber = 0, bool checkValidity = true);
             
             // Provide default implementations for constructors and assignments.
             Program() = default;
@@ -187,18 +189,11 @@ namespace storm {
             std::vector<Module> const& getModules() const;
             
             /*!
-             * Retrieves whether the program explicitly specifies an expression characterizing the initial states.
+             * Retrieves the initial construct of the program.
              *
-             * @return True iff the program specifies an expression defining the initial states.
+             * @return The initial construct of the program.
              */
-            bool definesInitialStatesExpression() const;
-            
-            /*!
-             * Retrieves an expression characterizing the initial states of the program.
-             *
-             * @return An expression characterizing the initial states.
-             */
-            storm::expressions::Expression getInitialStatesExpression() const;
+            storm::prism::InitialConstruct const& getInitialConstruct() const;
             
             /*!
              * Retrieves the set of actions present in the program.
@@ -336,12 +331,8 @@ namespace storm {
             // A mapping of reward models to their indices.
             std::map<std::string, uint_fast64_t> rewardModelToIndexMap;
             
-            // A flag that indicates whether the initial states of the program were given explicitly (in the form of an
-            // initial construct) or implicitly (attached to the variable declarations).
-            bool hasInitialStatesExpression;
-            
-            // The expression contained in the initial construct (if any).
-            storm::expressions::Expression initialStatesExpression;
+            // The initial construct of the program.
+            storm::prism::InitialConstruct initialConstruct;
             
             // The labels that are defined for this model.
             std::vector<Label> labels;
diff --git a/src/storage/prism/Update.cpp b/src/storage/prism/Update.cpp
index 5d65e6dd5..9082bc6f1 100644
--- a/src/storage/prism/Update.cpp
+++ b/src/storage/prism/Update.cpp
@@ -60,5 +60,5 @@ namespace storm {
             return stream;
         }
         
-    } // namespace ir
+    } // namespace prism
 } // namespace storm
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index dca09244a..5bf7bfd49 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -2,47 +2,20 @@
 #include "storm-config.h"
 #include "src/parser/PrismParser.h"
 
-TEST(PrismParser, SimpleParsingOnlyTest) {
-    std::string testInput =
-    R"(dtmc
-    module mod1
-        b : bool;
-        [a] true -> 1: (b'=true);
-    endmodule)";
-    
-    storm::prism::Program result;
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false));
-    EXPECT_EQ(1, result.getNumberOfModules());
-    EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType());
-}
-
-TEST(PrismParser, StandardModelParsingTest) {
-    storm::prism::Program result;
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/die.pm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/firewire.nm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3_5.pm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/two_dice.nm", false));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm", false));
-}
-
-TEST(PrismParser, StandardModelFullTest) {
+TEST(PrismParser, StandardModelTest) {
     storm::prism::Program result;
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/die.pm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/firewire.nm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3_5.pm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/two_dice.nm", true));
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/die.pm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/firewire.nm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3_5.pm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/two_dice.nm"));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm"));
 }
 
-TEST(PrismParser, SimpleFullTest) {
+TEST(PrismParser, SimpleTest) {
     std::string testInput =
     R"(dtmc
     module mod1
@@ -51,7 +24,7 @@ TEST(PrismParser, SimpleFullTest) {
     endmodule)";
     
     storm::prism::Program result;
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"));
     EXPECT_EQ(1, result.getNumberOfModules());
     EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType());
     
@@ -66,12 +39,12 @@ TEST(PrismParser, SimpleFullTest) {
         [] x=3 -> 1:(x'=4);
         [] x=4 -> 1:(x'=5);
     endmodule)";
-    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true));
+    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"));
     EXPECT_EQ(1, result.getNumberOfModules());
     EXPECT_EQ(storm::prism::Program::ModelType::MDP, result.getModelType());
 }
 
-TEST(PrismParser, ComplexFullTest) {
+TEST(PrismParser, ComplexTest) {
     std::string testInput =
     R"(ma
     
@@ -94,11 +67,11 @@ TEST(PrismParser, ComplexFullTest) {
         j : bool init c;
         k : [125..a] init a;
 
-        [a] test&false -> (i'=true)&(k'=1+1) + 1 : (k'=floor(a) <= max(k, b) - 1 + k);
+        [a] test&false -> (i'=true)&(k'=1+1) + 1 : (k'=floor(a) + max(k, b) - 1 + k);
     endmodule
                                               
     module mod2
-        [b] (k > 3) & false & (min(a, 0) < max(h, k)) -> 1-e: (j'=(1-a) * 2 + floor(f));
+        [b] (k > 3) & false & (min(a, 0) < max(h, k)) -> 1-e: (g'=(1-a) * 2 + floor(f) > 2);
     endmodule
     
     module mod3 = mod1 [ i = i1, j = j1, k = k1 ] endmodule
@@ -120,68 +93,11 @@ TEST(PrismParser, ComplexFullTest) {
     endrewards)";
     
     storm::prism::Program result;
-    result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true);
-    EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType());
-    EXPECT_EQ(3, result.getNumberOfModules());
-    EXPECT_EQ(2, result.getNumberOfRewardModels());
-    EXPECT_EQ(1, result.getNumberOfLabels());
-    EXPECT_TRUE(result.definesInitialStatesExpression());
-}
-
-TEST(PrismParser, ComplexParsingTest) {
-    std::string testInput =
-    R"(ma
-    
-    const int a;
-    const int b = 10;
-    const bool c;
-    const bool d = true | false;
-    const double e;
-    const double f = 9;
-    
-    formula test = (a >= 10 & (max(a, b) > floor(e)));
-
-    global g : bool init false;
-    global h : [0 .. b];
-    
-    module mod1
-        i : bool;
-        j : bool init c;
-        k : [125..a] init a;
-        [a] true -> (i'=true)&(h'=1+1) + 1 : (j'=floor(a) <= max(k, b) - 1 + k);
-    endmodule
-                                    
-    module mod2
-        [b] (x > 3) & false & (min(a, b0) < max(as8, b)) -> y: (x'=(1-g) * 2 + a);
-        [] s=1 -> (a'=a);
-        [read] c<N-1 -> 1 : (c'=floor(c) + 1);
-    endmodule
-                             
-    module mod3 = mod2 [ x = y ] endmodule
-             
-    label "mal" = max(x, i) > 0;
-                             
-    init
-        true
-    endinit
-                             
-    rewards "testrewards"
-        [stateRew] true : a + 7;
-        max(z, f) <= 8 : 2*b;
-    endrewards
-                             
-    rewards "testrewards2"
-        [stateRew] true : a + 7;
-        max(z, f) <= 8 : 2*b;
-    endrewards)";
-    
-    storm::prism::Program result;
-    result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false);
+    result = storm::parser::PrismParser::parseFromString(testInput, "testfile");
     EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType());
     EXPECT_EQ(3, result.getNumberOfModules());
     EXPECT_EQ(2, result.getNumberOfRewardModels());
     EXPECT_EQ(1, result.getNumberOfLabels());
-    EXPECT_TRUE(result.definesInitialStatesExpression());
 }
 
 TEST(PrismParser, IllegalInputTest) {
@@ -198,7 +114,7 @@ TEST(PrismParser, IllegalInputTest) {
     )";
     
     storm::prism::Program result;
-    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
     
     testInput =
     R"(dtmc
@@ -210,7 +126,7 @@ TEST(PrismParser, IllegalInputTest) {
         [] a < 3 -> 1: (a' = a+1); 
     endmodule)";
     
-    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
     
     testInput =
     R"(dtmc
@@ -223,7 +139,7 @@ TEST(PrismParser, IllegalInputTest) {
         [] c < 3 -> 1: (c' = c+1); 
     endmodule)";
     
-    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
     
     testInput =
     R"(dtmc
@@ -245,5 +161,63 @@ TEST(PrismParser, IllegalInputTest) {
 
     )";
     
-    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false), storm::exceptions::WrongFormatException);
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c < 3 -> 1: (c' = c+1);
+    endmodule
+                    
+    module mod2
+        [] c < 3 -> 1: (c' = c+1);
+    endmodule)";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
+                        
+    testInput =
+    R"(dtmc
+                        
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c < 3 -> 1: (c' = c+1)&(c'=c-1);
+    endmodule)";
+                                        
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c < 3 -> 1: (c' = true || false);
+    endmodule)";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c + 3 -> 1: (c' = 1);
+    endmodule)";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
+    
+    testInput =
+    R"(dtmc
+    
+    module mod1
+        c : [0 .. 8] init 1;
+        [] c + 3 -> 1: (c' = 1);
+    endmodule
+    
+    label "test" = c + 1;
+    
+    )";
+    
+    EXPECT_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile"), storm::exceptions::WrongFormatException);
 }
\ No newline at end of file

From 9b31033d054d2ddad11be356bd358ed57fd6bfa7 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 10:31:04 +0200
Subject: [PATCH 102/147] Added options for Cudd manager to set precision,
 reordering technique and maxmem.

Former-commit-id: c18bfab5184f6dab880517ecbe50265774a6d7d4
---
 src/storage/dd/CuddDdManager.cpp | 37 +++++++++++++++++++++++++++++---
 src/storage/dd/CuddDdManager.h   |  4 +++-
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 6c8c66683..270d3f9d9 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -4,12 +4,36 @@
 
 #include "src/storage/dd/CuddDdManager.h"
 #include "src/exceptions/InvalidArgumentException.h"
+#include "src/settings/Settings.h"
+
+bool CuddOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
+    // Set up option for reordering.
+    std::vector<std::string> reorderingTechniques;
+    reorderingTechniques.push_back("none");
+    reorderingTechniques.push_back("sift");
+    reorderingTechniques.push_back("ssift");
+    reorderingTechniques.push_back("gsift");
+    reorderingTechniques.push_back("win2");
+    reorderingTechniques.push_back("win3");
+    reorderingTechniques.push_back("win4");
+    reorderingTechniques.push_back("annealing");
+    reorderingTechniques.push_back("genetic");
+    reorderingTechniques.push_back("exact");
+	instance->addOption(storm::settings::OptionBuilder("Cudd", "reorder", "", "Sets the reordering technique used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used by Cudd's reordering routines. Must be in {\"none\", \"sift\", \"ssift\", \"gsift\", \"win2\", \"win3\", \"win4\", \"annealing\", \"genetic\", \"exact\"}.").setDefaultValueString("gsift").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(reorderingTechniques)).build()).build());
+    
+    // Set up options for precision and maximal memory available to Cudd.
+    instance->addOption(storm::settings::OptionBuilder("Cudd", "cuddprec", "", "Sets the precision used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision up to which to constants are considered to be different.").setDefaultValueDouble(1e-15).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
+    
+    instance->addOption(storm::settings::OptionBuilder("Cudd", "maxmem", "", "Sets the upper bound of memory available to Cudd in MB.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("mb", "The memory available to Cudd (0 means unlimited).").setDefaultValueUnsignedInteger(2048).build()).build());
+    
+    return true;
+});
 
 namespace storm {
     namespace dd {
         DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
-            
-            this->cuddManager.SetEpsilon(1.0e-15);
+            this->cuddManager.SetMaxMemory(storm::settings::Settings::getInstance()->getOptionByLongName("maxmem").getArgument(0).getValueAsUnsignedInteger() * 1024);
+            this->cuddManager.SetEpsilon(storm::settings::Settings::getInstance()->getOptionByLongName("cuddprec").getArgument(0).getValueAsDouble());
         }
         
         Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() {
@@ -124,7 +148,7 @@ namespace storm {
             metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, variables, this->shared_from_this()));
         }
         
-        void DdManager<DdType::CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
+        void DdManager<DdType::CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high, bool fixedGroup) {
             // Make sure that at least one meta variable is added.
             if (names.size() == 0) {
                 throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables.";
@@ -158,6 +182,13 @@ namespace storm {
                 }
             }
             
+            // If required, we group the bits on the same layer of the interleaved meta variables.
+            if (fixedGroup) {
+                for (uint_fast64_t i = 0; i < names.size(); ++i) {
+                    this->getCuddManager().MakeTreeNode(variables[i].front().getCuddAdd().NodeReadIndex(), names.size(), MTR_FIXED);
+                }
+            }
+            
             // Now add the meta variables.
             for (uint_fast64_t i = 0; i < names.size(); ++i) {
                 metaVariableMap.emplace(names[i], DdMetaVariable<DdType::CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 6df3dc25c..25844598c 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -103,8 +103,10 @@ namespace storm {
              * @param names The names of the variables.
              * @param low The lowest value of the ranges of the variables.
              * @param high The highest value of the ranges of the variables.
+             * @param fixedGroup If set to true, the interleaved bits of the meta variable are always kept together as
+             * a group during a potential reordering.
              */
-            void addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high);
+            void addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high, bool fixedGroup = true);
             
             /*!
              * Retrieves the meta variable with the given name if it exists.

From d00cf794f18d5d40510e765ab0b2dde6704c16ff Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 11:28:41 +0200
Subject: [PATCH 103/147] Fixed wrong invocation of option system so all tests
 pass again, sorry about that, Philipp. :)

Former-commit-id: 475923edc48e607c44e7ca6186a9541ad3c2a9f5
---
 src/storage/dd/CuddDdManager.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 270d3f9d9..64261d0aa 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -7,6 +7,11 @@
 #include "src/settings/Settings.h"
 
 bool CuddOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
+    // Set up options for precision and maximal memory available to Cudd.
+    instance->addOption(storm::settings::OptionBuilder("Cudd", "cuddprec", "", "Sets the precision used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision up to which to constants are considered to be different.").setDefaultValueDouble(1e-15).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
+
+    instance->addOption(storm::settings::OptionBuilder("Cudd", "cuddmaxmem", "", "Sets the upper bound of memory available to Cudd in MB.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("mb", "The memory available to Cudd (0 means unlimited).").setDefaultValueUnsignedInteger(2048).build()).build());
+    
     // Set up option for reordering.
     std::vector<std::string> reorderingTechniques;
     reorderingTechniques.push_back("none");
@@ -21,18 +26,13 @@ bool CuddOptionsRegistered = storm::settings::Settings::registerNewModule([] (st
     reorderingTechniques.push_back("exact");
 	instance->addOption(storm::settings::OptionBuilder("Cudd", "reorder", "", "Sets the reordering technique used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used by Cudd's reordering routines. Must be in {\"none\", \"sift\", \"ssift\", \"gsift\", \"win2\", \"win3\", \"win4\", \"annealing\", \"genetic\", \"exact\"}.").setDefaultValueString("gsift").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(reorderingTechniques)).build()).build());
     
-    // Set up options for precision and maximal memory available to Cudd.
-    instance->addOption(storm::settings::OptionBuilder("Cudd", "cuddprec", "", "Sets the precision used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision up to which to constants are considered to be different.").setDefaultValueDouble(1e-15).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
-    
-    instance->addOption(storm::settings::OptionBuilder("Cudd", "maxmem", "", "Sets the upper bound of memory available to Cudd in MB.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("mb", "The memory available to Cudd (0 means unlimited).").setDefaultValueUnsignedInteger(2048).build()).build());
-    
     return true;
 });
 
 namespace storm {
     namespace dd {
         DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
-            this->cuddManager.SetMaxMemory(storm::settings::Settings::getInstance()->getOptionByLongName("maxmem").getArgument(0).getValueAsUnsignedInteger() * 1024);
+            this->cuddManager.SetMaxMemory(storm::settings::Settings::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024);
             this->cuddManager.SetEpsilon(storm::settings::Settings::getInstance()->getOptionByLongName("cuddprec").getArgument(0).getValueAsDouble());
         }
         

From c6976dd8b591d02c5d5bed6524ee2d7449e1e975 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 13:14:13 +0200
Subject: [PATCH 104/147] Added some query methods for new expression classes.

Former-commit-id: 0633c7740e8f9df4f016a86c30e533974dd4ca86
---
 src/storage/expressions/BaseExpression.cpp    | 31 +++++++++-
 src/storage/expressions/BaseExpression.h      | 55 +++++++++++++++++-
 .../BinaryBooleanFunctionExpression.cpp       |  2 +-
 src/storage/expressions/BinaryExpression.cpp  | 26 ++++++++-
 src/storage/expressions/BinaryExpression.h    |  5 +-
 .../expressions/BooleanLiteralExpression.cpp  |  6 +-
 .../expressions/BooleanLiteralExpression.h    |  3 +-
 .../expressions/ConstantExpression.cpp        | 12 ++++
 src/storage/expressions/ConstantExpression.h  |  3 +
 .../expressions/DoubleLiteralExpression.cpp   |  6 +-
 .../expressions/DoubleLiteralExpression.h     |  3 +-
 src/storage/expressions/Expression.cpp        | 28 +++++++++
 src/storage/expressions/Expression.h          | 57 ++++++++++++++++++-
 .../expressions/IntegerLiteralExpression.cpp  |  6 +-
 .../expressions/IntegerLiteralExpression.h    |  3 +-
 src/storage/expressions/UnaryExpression.cpp   | 20 ++++++-
 src/storage/expressions/UnaryExpression.h     |  5 +-
 .../expressions/VariableExpression.cpp        |  8 +++
 src/storage/expressions/VariableExpression.h  |  2 +
 test/functional/storage/ExpressionTest.cpp    | 20 +++----
 20 files changed, 271 insertions(+), 30 deletions(-)

diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index bb4ea0921..346871b01 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -1,6 +1,7 @@
 #include "src/storage/expressions/BaseExpression.h"
 #include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/InvalidTypeException.h"
+#include "src/exceptions/InvalidAccessException.h"
 
 namespace storm {
     namespace expressions {        
@@ -36,10 +37,38 @@ namespace storm {
             LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
         }
         
+        uint_fast64_t BaseExpression::getArity() const {
+            return 0;
+        }
+        
+        std::shared_ptr<BaseExpression const> BaseExpression::getOperand(uint_fast64_t operandIndex) const {
+            LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to access operand " << operandIndex << " in expression of arity 0.");
+        }
+        
+        std::string const& BaseExpression::getIdentifier() const {
+            LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to access identifier of non-constant, non-variable expression.");
+        }
+        
+        bool BaseExpression::containsVariables() const {
+            return false;
+        }
+        
+        bool BaseExpression::hasConstantValue() const {
+            return false;
+        }
+        
+        bool BaseExpression::isLiteral() const {
+            return false;
+        }
+        
         bool BaseExpression::isConstant() const {
             return false;
         }
-
+        
+        bool BaseExpression::isVariable() const {
+            return false;
+        }
+        
         bool BaseExpression::isTrue() const {
             return false;
         }
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index fb3df4514..fb88ffae8 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -74,12 +74,63 @@ namespace storm {
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const;
 
             /*!
-             * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants.
+             * Returns the arity of the expression.
              *
-             * @return True iff the expression is constant.
+             * @return The arity of the expression.
+             */
+            virtual uint_fast64_t getArity() const;
+            
+            /*!
+             * Retrieves the given operand from the expression.
+             *
+             * @param operandIndex The index of the operand to retrieve. This must be lower than the arity of the expression.
+             * @return The operand at the given index.
+             */
+            virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const;
+            
+            /*!
+             * Retrieves the identifier associated with this expression. This is only legal to call if the expression
+             * is either a constant or a variable.
+             *
+             * @return The identifier associated with this expression.
+             */
+            virtual std::string const& getIdentifier() const;
+            
+            /*!
+             * Retrieves whether the expression has a constant value, i.e., does not involve variables or constants.
+             *
+             * @return True iff the expression has a constant value.
+             */
+            virtual bool hasConstantValue() const;
+            
+            /*!
+             * Retrieves whether the expression contains a variable.
+             *
+             * @return True iff the expression contains a variable.
+             */
+            virtual bool containsVariables() const;
+            
+            /*!
+             * Retrieves whether the expression is a literal.
+             *
+             * @return True iff the expression is a literal.
+             */
+            virtual bool isLiteral() const;
+            
+            /*!
+             * Retrieves whether the expression is a constant.
+             *
+             * @return True iff the expression is a constant.
              */
             virtual bool isConstant() const;
             
+            /*!
+             * Retrieves whether the expression is a variable.
+             *
+             * @return True iff the expression is a variable.
+             */
+            virtual bool isVariable() const;
+            
             /*!
              * Checks if the expression is equal to the boolean literal true.
              *
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index 02cd9686b..e270293a8 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -30,7 +30,7 @@ namespace storm {
             
             return result;
         }
-        
+                
         std::shared_ptr<BaseExpression const> BinaryBooleanFunctionExpression::simplify() const {
             std::shared_ptr<BaseExpression const> firstOperandSimplified = this->getFirstOperand()->simplify();
             std::shared_ptr<BaseExpression const> secondOperandSimplified = this->getSecondOperand()->simplify();
diff --git a/src/storage/expressions/BinaryExpression.cpp b/src/storage/expressions/BinaryExpression.cpp
index cfd18447c..bdb885993 100644
--- a/src/storage/expressions/BinaryExpression.cpp
+++ b/src/storage/expressions/BinaryExpression.cpp
@@ -1,13 +1,20 @@
 #include "src/storage/expressions/BinaryExpression.h"
 
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidAccessException.h"
+
 namespace storm {
     namespace expressions {
         BinaryExpression::BinaryExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand) : BaseExpression(returnType), firstOperand(firstOperand), secondOperand(secondOperand) {
             // Intentionally left empty.
         }
-                
-        bool BinaryExpression::isConstant() const {
-            return this->getFirstOperand()->isConstant() && this->getSecondOperand()->isConstant();
+        
+        bool BinaryExpression::containsVariables() const {
+            return this->getFirstOperand()->containsVariables() || this->getSecondOperand()->containsVariables();
+        }
+        
+        bool BinaryExpression::hasConstantValue() const {
+            return this->getFirstOperand()->hasConstantValue() && this->getSecondOperand()->hasConstantValue();
         }
         
         std::set<std::string> BinaryExpression::getVariables() const {
@@ -31,5 +38,18 @@ namespace storm {
         std::shared_ptr<BaseExpression const> const& BinaryExpression::getSecondOperand() const {
             return this->secondOperand;
         }
+        
+        uint_fast64_t BinaryExpression::getArity() const {
+            return 2;
+        }
+        
+        std::shared_ptr<BaseExpression const> BinaryExpression::getOperand(uint_fast64_t operandIndex) const {
+            LOG_THROW(operandIndex < 2, storm::exceptions::InvalidAccessException, "Unable to access operand " << operandIndex << " in expression of arity 2.");
+            if (operandIndex == 1) {
+                return this->getFirstOperand();
+            } else {
+                return this->getSecondOperand();
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h
index 640297a91..5016bd247 100644
--- a/src/storage/expressions/BinaryExpression.h
+++ b/src/storage/expressions/BinaryExpression.h
@@ -30,7 +30,10 @@ namespace storm {
             virtual ~BinaryExpression() = default;
 
             // Override base class methods.
-            virtual bool isConstant() const override;
+            virtual bool containsVariables() const override;
+            virtual bool hasConstantValue() const override;
+            virtual uint_fast64_t getArity() const override;
+            virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             
diff --git a/src/storage/expressions/BooleanLiteralExpression.cpp b/src/storage/expressions/BooleanLiteralExpression.cpp
index 6ef15fe83..b0a65594c 100644
--- a/src/storage/expressions/BooleanLiteralExpression.cpp
+++ b/src/storage/expressions/BooleanLiteralExpression.cpp
@@ -10,7 +10,11 @@ namespace storm {
             return this->getValue();
         }
         
-        bool BooleanLiteralExpression::isConstant() const {
+        bool BooleanLiteralExpression::isLiteral() const {
+            return true;
+        }
+        
+        bool BooleanLiteralExpression::hasConstantValue() const {
             return true;
         }
         
diff --git a/src/storage/expressions/BooleanLiteralExpression.h b/src/storage/expressions/BooleanLiteralExpression.h
index 6c0413236..31a7d5dca 100644
--- a/src/storage/expressions/BooleanLiteralExpression.h
+++ b/src/storage/expressions/BooleanLiteralExpression.h
@@ -26,7 +26,8 @@ namespace storm {
 
             // Override base class methods.
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
-            virtual bool isConstant() const override;
+            virtual bool isLiteral() const override;
+            virtual bool hasConstantValue() const override;
             virtual bool isTrue() const override;
             virtual bool isFalse() const override;
             virtual std::set<std::string> getVariables() const override;
diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp
index d09a75573..ec1efc11a 100644
--- a/src/storage/expressions/ConstantExpression.cpp
+++ b/src/storage/expressions/ConstantExpression.cpp
@@ -18,6 +18,18 @@ namespace storm {
             return this->constantName;
         }
         
+        bool ConstantExpression::isConstant() const {
+            return true;
+        }
+        
+        bool ConstantExpression::hasConstantValue() const {
+            return false;
+        }
+        
+        std::string const& ConstantExpression::getIdentifier() const {
+            return this->getConstantName();
+        }
+        
         void ConstantExpression::printToStream(std::ostream& stream) const {
             stream << this->getConstantName();
         }
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
index 50f00c235..fd79fd51e 100644
--- a/src/storage/expressions/ConstantExpression.h
+++ b/src/storage/expressions/ConstantExpression.h
@@ -26,6 +26,9 @@ namespace storm {
             virtual ~ConstantExpression() = default;
             
             // Override base class methods.
+            virtual bool isConstant() const override;
+            virtual bool hasConstantValue() const override;
+            virtual std::string const& getIdentifier() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index 642a1817f..a319c40d8 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -10,7 +10,11 @@ namespace storm {
             return this->getValue();
         }
         
-        bool DoubleLiteralExpression::isConstant() const {
+        bool DoubleLiteralExpression::isLiteral() const {
+            return true;
+        }
+
+        bool DoubleLiteralExpression::hasConstantValue() const {
             return true;
         }
         
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index e4bc28b81..5395a34a8 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -26,7 +26,8 @@ namespace storm {
             
             // Override base class methods.
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
-            virtual bool isConstant() const override;
+            virtual bool isLiteral() const override;
+            virtual bool hasConstantValue() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 51d085fe4..ae787faed 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -68,10 +68,38 @@ namespace storm {
             return Expression(this->getBaseExpression().simplify());
         }
         
+        uint_fast64_t Expression::getArity() const {
+            return this->getBaseExpression().getArity();
+        }
+        
+        Expression Expression::getOperand(uint_fast64_t operandIndex) const {
+            return Expression(this->getBaseExpression().getOperand(operandIndex));
+        }
+        
+        std::string const& Expression::getIdentifier() const {
+            return this->getBaseExpression().getIdentifier();
+        }
+        
+        bool Expression::hasConstantValue() const {
+            return this->getBaseExpression().hasConstantValue();
+        }
+        
+        bool Expression::containsVariables() const {
+            return this->getBaseExpression().containsVariables();
+        }
+        
+        bool Expression::isLiteral() const {
+            return this->isLiteral();
+        }
+        
         bool Expression::isConstant() const {
             return this->getBaseExpression().isConstant();
         }
         
+        bool Expression::isVariable() const {
+            return this->getBaseExpression().isVariable();
+        }
+        
         bool Expression::isTrue() const {
             return this->getBaseExpression().isTrue();
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 36c367639..11636521b 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -164,11 +164,62 @@ namespace storm {
             Expression simplify();
             
             /*!
-             * Retrieves whether the expression is constant, i.e., contains no variables or undefined constants.
+             * Retrieves the arity of the expression.
              *
-             * @return True iff the expression is constant.
+             * @return The arity of the expression.
              */
-            bool isConstant() const;
+            uint_fast64_t getArity() const;
+            
+            /*!
+             * Retrieves the given operand from the expression.
+             *
+             * @param operandIndex The index of the operand to retrieve. This must be lower than the arity of the expression.
+             * @return The operand at the given index.
+             */
+            Expression getOperand(uint_fast64_t operandIndex) const;
+            
+            /*!
+             * Retrieves the identifier associated with this expression. This is only legal to call if the expression
+             * is either a constant or a variable.
+             *
+             * @return The identifier associated with this expression.
+             */
+            virtual std::string const& getIdentifier() const;
+            
+            /*!
+             * Retrieves whether the expression has a constant value, i.e., does not involve variables.
+             *
+             * @return True iff the expression has a constant value.
+             */
+            virtual bool hasConstantValue() const;
+            
+            /*!
+             * Retrieves whether the expression contains a variable.
+             *
+             * @return True iff the expression contains a variable.
+             */
+            virtual bool containsVariables() const;
+            
+            /*!
+             * Retrieves whether the expression is a literal.
+             *
+             * @return True iff the expression is a literal.
+             */
+            virtual bool isLiteral() const;
+            
+            /*!
+             * Retrieves whether the expression is a constant.
+             *
+             * @return True iff the expression is a constant.
+             */
+            virtual bool isConstant() const;
+            
+            /*!
+             * Retrieves whether the expression is a variable.
+             *
+             * @return True iff the expression is a variable.
+             */
+            virtual bool isVariable() const;
             
             /*!
              * Checks if the expression is equal to the boolean literal true.
diff --git a/src/storage/expressions/IntegerLiteralExpression.cpp b/src/storage/expressions/IntegerLiteralExpression.cpp
index 5e6404fc8..5bdb9c1a9 100644
--- a/src/storage/expressions/IntegerLiteralExpression.cpp
+++ b/src/storage/expressions/IntegerLiteralExpression.cpp
@@ -14,7 +14,11 @@ namespace storm {
             return static_cast<double>(this->evaluateAsInt(valuation));
         }
         
-        bool IntegerLiteralExpression::isConstant() const {
+        bool IntegerLiteralExpression::isLiteral() const {
+            return true;
+        }
+        
+        bool IntegerLiteralExpression::hasConstantValue() const {
             return true;
         }
         
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
index 8d50fe688..2a45eb5cc 100644
--- a/src/storage/expressions/IntegerLiteralExpression.h
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -27,7 +27,8 @@ namespace storm {
             // Override base class methods.
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
-            virtual bool isConstant() const override;
+            virtual bool isLiteral() const override;
+            virtual bool hasConstantValue() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp
index 1e2d9135e..8349a8aac 100644
--- a/src/storage/expressions/UnaryExpression.cpp
+++ b/src/storage/expressions/UnaryExpression.cpp
@@ -1,13 +1,20 @@
 #include "src/storage/expressions/UnaryExpression.h"
 
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidAccessException.h"
+
 namespace storm {
     namespace expressions {
         UnaryExpression::UnaryExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& operand) : BaseExpression(returnType), operand(operand) {
             // Intentionally left empty.
         }
 
-        bool UnaryExpression::isConstant() const {
-            return this->getOperand()->isConstant();
+        bool UnaryExpression::containsVariables() const {
+            return this->getOperand()->containsVariables();
+        }
+        
+        bool UnaryExpression::hasConstantValue() const {
+            return this->getOperand()->hasConstantValue();
         }
         
         std::set<std::string> UnaryExpression::getVariables() const {
@@ -21,5 +28,14 @@ namespace storm {
         std::shared_ptr<BaseExpression const> const& UnaryExpression::getOperand() const {
             return this->operand;
         }
+        
+        uint_fast64_t UnaryExpression::getArity() const {
+            return 1;
+        }
+        
+        std::shared_ptr<BaseExpression const> UnaryExpression::getOperand(uint_fast64_t operandIndex) const {
+            LOG_THROW(operandIndex == 0, storm::exceptions::InvalidAccessException, "Unable to access operand " << operandIndex << " in expression of arity 2.");
+            return this->getOperand();
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
index f81bc08ad..e071aa979 100644
--- a/src/storage/expressions/UnaryExpression.h
+++ b/src/storage/expressions/UnaryExpression.h
@@ -26,7 +26,10 @@ namespace storm {
             virtual ~UnaryExpression() = default;
             
             // Override base class methods.
-            virtual bool isConstant() const override;
+            virtual bool containsVariables() const override;
+            virtual bool hasConstantValue() const override;
+            virtual uint_fast64_t getArity() const override;
+            virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
index d7765f14a..88cb7ba86 100644
--- a/src/storage/expressions/VariableExpression.cpp
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -41,6 +41,14 @@ namespace storm {
             return 0;
         }
         
+        std::string const& VariableExpression::getIdentifier() const {
+            return this->getVariableName();
+        }
+        
+        bool VariableExpression::containsVariables() const {
+            return true;
+        }
+        
         std::set<std::string> VariableExpression::getVariables() const {
             return {this->getVariableName()};
         }
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index 2d83b7160..e6d9366f7 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -29,6 +29,8 @@ namespace storm {
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
+            virtual std::string const& getIdentifier() const override;
+            virtual bool containsVariables() const override;
             virtual std::set<std::string> getVariables() const override;
             virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 89ca71e9b..893149a23 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -44,70 +44,70 @@ TEST(Expression, AccessorTest) {
     ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
     
     EXPECT_TRUE(trueExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_TRUE(trueExpression.isConstant());
+    EXPECT_TRUE(trueExpression.hasConstantValue());
     EXPECT_TRUE(trueExpression.isTrue());
     EXPECT_FALSE(trueExpression.isFalse());
     EXPECT_TRUE(trueExpression.getVariables() == std::set<std::string>());
     EXPECT_TRUE(trueExpression.getConstants() == std::set<std::string>());
     
     EXPECT_TRUE(falseExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_TRUE(falseExpression.isConstant());
+    EXPECT_TRUE(falseExpression.hasConstantValue());
     EXPECT_FALSE(falseExpression.isTrue());
     EXPECT_TRUE(falseExpression.isFalse());
     EXPECT_TRUE(falseExpression.getVariables() == std::set<std::string>());
     EXPECT_TRUE(falseExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(threeExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    EXPECT_TRUE(threeExpression.isConstant());
+    EXPECT_TRUE(threeExpression.hasConstantValue());
     EXPECT_FALSE(threeExpression.isTrue());
     EXPECT_FALSE(threeExpression.isFalse());
     EXPECT_TRUE(threeExpression.getVariables() == std::set<std::string>());
     EXPECT_TRUE(threeExpression.getConstants() == std::set<std::string>());
     
     EXPECT_TRUE(piExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    EXPECT_TRUE(piExpression.isConstant());
+    EXPECT_TRUE(piExpression.hasConstantValue());
     EXPECT_FALSE(piExpression.isTrue());
     EXPECT_FALSE(piExpression.isFalse());
     EXPECT_TRUE(piExpression.getVariables() == std::set<std::string>());
     EXPECT_TRUE(piExpression.getConstants() == std::set<std::string>());
     
     EXPECT_TRUE(boolVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_FALSE(boolVarExpression.isConstant());
+    EXPECT_FALSE(boolVarExpression.hasConstantValue());
     EXPECT_FALSE(boolVarExpression.isTrue());
     EXPECT_FALSE(boolVarExpression.isFalse());
     EXPECT_TRUE(boolVarExpression.getVariables() == std::set<std::string>({"x"}));
     EXPECT_TRUE(boolVarExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(intVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    EXPECT_FALSE(intVarExpression.isConstant());
+    EXPECT_FALSE(intVarExpression.hasConstantValue());
     EXPECT_FALSE(intVarExpression.isTrue());
     EXPECT_FALSE(intVarExpression.isFalse());
     EXPECT_TRUE(intVarExpression.getVariables() == std::set<std::string>({"y"}));
     EXPECT_TRUE(intVarExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(doubleVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    EXPECT_FALSE(doubleVarExpression.isConstant());
+    EXPECT_FALSE(doubleVarExpression.hasConstantValue());
     EXPECT_FALSE(doubleVarExpression.isTrue());
     EXPECT_FALSE(doubleVarExpression.isFalse());
     EXPECT_TRUE(doubleVarExpression.getVariables() == std::set<std::string>({"z"}));
     EXPECT_TRUE(doubleVarExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(boolConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_FALSE(boolConstExpression.isConstant());
+    EXPECT_FALSE(boolConstExpression.hasConstantValue());
     EXPECT_FALSE(boolConstExpression.isTrue());
     EXPECT_FALSE(boolConstExpression.isFalse());
     EXPECT_TRUE(boolConstExpression.getVariables() == std::set<std::string>());
     EXPECT_TRUE(boolConstExpression.getConstants() == std::set<std::string>({"a"}));
     
     EXPECT_TRUE(intConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    EXPECT_FALSE(intConstExpression.isConstant());
+    EXPECT_FALSE(intConstExpression.hasConstantValue());
     EXPECT_FALSE(intConstExpression.isTrue());
     EXPECT_FALSE(intConstExpression.isFalse());
     EXPECT_TRUE(intConstExpression.getVariables() == std::set<std::string>());
     EXPECT_TRUE(intConstExpression.getConstants() == std::set<std::string>({"b"}));
 
     EXPECT_TRUE(doubleConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    EXPECT_FALSE(doubleConstExpression.isConstant());
+    EXPECT_FALSE(doubleConstExpression.hasConstantValue());
     EXPECT_FALSE(doubleConstExpression.isTrue());
     EXPECT_FALSE(doubleConstExpression.isFalse());
     EXPECT_TRUE(doubleConstExpression.getVariables() == std::set<std::string>());

From 219af9b43ba09c53cd124ab261a684bc1efff9c6 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 14:22:22 +0200
Subject: [PATCH 105/147] Removed constants from expressions. Even though PRISM
 has the concept of constants and variables, it currently makes no sense to
 distinguish them in our expression classes.

Former-commit-id: 787e921e2c37ee120d30772bb3412e9aa91b2b78
---
 src/parser/PrismParser.cpp                    |  12 +-
 src/storage/expressions/BaseExpression.cpp    |   8 --
 src/storage/expressions/BaseExpression.h      |  23 +---
 src/storage/expressions/BinaryExpression.cpp  |  11 --
 src/storage/expressions/BinaryExpression.h    |   2 -
 .../expressions/BooleanConstantExpression.cpp |  23 ----
 .../expressions/BooleanConstantExpression.h   |  35 -----
 .../expressions/BooleanLiteralExpression.cpp  |   8 --
 .../expressions/BooleanLiteralExpression.h    |   2 -
 .../expressions/ConstantExpression.cpp        |  37 ------
 src/storage/expressions/ConstantExpression.h  |  53 --------
 .../expressions/DoubleConstantExpression.cpp  |  23 ----
 .../expressions/DoubleConstantExpression.h    |  35 -----
 .../expressions/DoubleLiteralExpression.cpp   |   8 --
 .../expressions/DoubleLiteralExpression.h     |   2 -
 src/storage/expressions/Expression.cpp        |  48 +------
 src/storage/expressions/Expression.h          |  48 +------
 src/storage/expressions/ExpressionVisitor.h   |   7 -
 src/storage/expressions/Expressions.h         |   5 +-
 .../IdentifierSubstitutionVisitor.cpp         |  50 +-------
 .../IdentifierSubstitutionVisitor.h           |   3 -
 .../expressions/IfThenElseExpression.cpp      |  13 --
 .../expressions/IfThenElseExpression.h        |   2 -
 .../expressions/IntegerConstantExpression.cpp |  27 ----
 .../expressions/IntegerConstantExpression.h   |  36 ------
 .../expressions/IntegerLiteralExpression.cpp  |   8 --
 .../expressions/IntegerLiteralExpression.h    |   2 -
 .../expressions/SubstitutionVisitor.cpp       |  33 -----
 src/storage/expressions/SubstitutionVisitor.h |   3 -
 src/storage/expressions/TypeCheckVisitor.cpp  |  23 +---
 src/storage/expressions/TypeCheckVisitor.h    |   3 -
 src/storage/expressions/UnaryExpression.cpp   |   8 --
 src/storage/expressions/UnaryExpression.h     |   2 -
 .../expressions/VariableExpression.cpp        |   4 -
 src/storage/expressions/VariableExpression.h  |   1 -
 src/storage/prism/Program.cpp                 |  70 +++++-----
 test/functional/storage/ExpressionTest.cpp    | 121 +++++-------------
 37 files changed, 83 insertions(+), 716 deletions(-)
 delete mode 100644 src/storage/expressions/BooleanConstantExpression.cpp
 delete mode 100644 src/storage/expressions/BooleanConstantExpression.h
 delete mode 100644 src/storage/expressions/ConstantExpression.cpp
 delete mode 100644 src/storage/expressions/ConstantExpression.h
 delete mode 100644 src/storage/expressions/DoubleConstantExpression.cpp
 delete mode 100644 src/storage/expressions/DoubleConstantExpression.h
 delete mode 100644 src/storage/expressions/IntegerConstantExpression.cpp
 delete mode 100644 src/storage/expressions/IntegerConstantExpression.h

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 727579dff..d4686bcff 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -572,7 +572,7 @@ namespace storm {
         storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanVariable(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, this->getFilename());
         }
@@ -580,7 +580,7 @@ namespace storm {
         storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerVariable(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, this->getFilename());
         }
@@ -588,7 +588,7 @@ namespace storm {
         storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleVariable(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, this->getFilename());
         }
@@ -596,7 +596,7 @@ namespace storm {
         storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanVariable(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, expression, this->getFilename());
         }
@@ -604,7 +604,7 @@ namespace storm {
         storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerVariable(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, expression, this->getFilename());
         }
@@ -612,7 +612,7 @@ namespace storm {
         storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
-                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
+                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleVariable(newConstant));
             }
             return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, expression, this->getFilename());
         }
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index 346871b01..2aef5ab6e 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -53,18 +53,10 @@ namespace storm {
             return false;
         }
         
-        bool BaseExpression::hasConstantValue() const {
-            return false;
-        }
-        
         bool BaseExpression::isLiteral() const {
             return false;
         }
         
-        bool BaseExpression::isConstant() const {
-            return false;
-        }
-        
         bool BaseExpression::isVariable() const {
             return false;
         }
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index fb88ffae8..79dc09c1d 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -90,19 +90,12 @@ namespace storm {
             
             /*!
              * Retrieves the identifier associated with this expression. This is only legal to call if the expression
-             * is either a constant or a variable.
+             * is a variable.
              *
              * @return The identifier associated with this expression.
              */
             virtual std::string const& getIdentifier() const;
             
-            /*!
-             * Retrieves whether the expression has a constant value, i.e., does not involve variables or constants.
-             *
-             * @return True iff the expression has a constant value.
-             */
-            virtual bool hasConstantValue() const;
-            
             /*!
              * Retrieves whether the expression contains a variable.
              *
@@ -117,13 +110,6 @@ namespace storm {
              */
             virtual bool isLiteral() const;
             
-            /*!
-             * Retrieves whether the expression is a constant.
-             *
-             * @return True iff the expression is a constant.
-             */
-            virtual bool isConstant() const;
-            
             /*!
              * Retrieves whether the expression is a variable.
              *
@@ -152,13 +138,6 @@ namespace storm {
              */
             virtual std::set<std::string> getVariables() const = 0;
             
-            /*!
-             * Retrieves the set of all constants that appear in the expression.
-             *
-             * @return The set of all constants that appear in the expression.
-             */
-            virtual std::set<std::string> getConstants() const = 0;
-            
             /*!
              * Simplifies the expression according to some simple rules.
              *
diff --git a/src/storage/expressions/BinaryExpression.cpp b/src/storage/expressions/BinaryExpression.cpp
index bdb885993..0ca77aa0c 100644
--- a/src/storage/expressions/BinaryExpression.cpp
+++ b/src/storage/expressions/BinaryExpression.cpp
@@ -13,10 +13,6 @@ namespace storm {
             return this->getFirstOperand()->containsVariables() || this->getSecondOperand()->containsVariables();
         }
         
-        bool BinaryExpression::hasConstantValue() const {
-            return this->getFirstOperand()->hasConstantValue() && this->getSecondOperand()->hasConstantValue();
-        }
-        
         std::set<std::string> BinaryExpression::getVariables() const {
             std::set<std::string> firstVariableSet = this->getFirstOperand()->getVariables();
             std::set<std::string> secondVariableSet = this->getSecondOperand()->getVariables();
@@ -24,13 +20,6 @@ namespace storm {
             return firstVariableSet;
         }
         
-        std::set<std::string> BinaryExpression::getConstants() const {
-            std::set<std::string> firstConstantSet = this->getFirstOperand()->getVariables();
-            std::set<std::string> secondConstantSet = this->getSecondOperand()->getVariables();
-            firstConstantSet.insert(secondConstantSet.begin(), secondConstantSet.end());
-            return firstConstantSet;
-        }
-        
         std::shared_ptr<BaseExpression const> const& BinaryExpression::getFirstOperand() const {
             return this->firstOperand;
         }
diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h
index 5016bd247..dd81343ac 100644
--- a/src/storage/expressions/BinaryExpression.h
+++ b/src/storage/expressions/BinaryExpression.h
@@ -31,11 +31,9 @@ namespace storm {
 
             // Override base class methods.
             virtual bool containsVariables() const override;
-            virtual bool hasConstantValue() const override;
             virtual uint_fast64_t getArity() const override;
             virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             
             /*!
              * Retrieves the first operand of the expression.
diff --git a/src/storage/expressions/BooleanConstantExpression.cpp b/src/storage/expressions/BooleanConstantExpression.cpp
deleted file mode 100644
index de87dab48..000000000
--- a/src/storage/expressions/BooleanConstantExpression.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "src/storage/expressions/BooleanConstantExpression.h"
-#include "src/exceptions/ExceptionMacros.h"
-
-namespace storm {
-    namespace expressions {
-        BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::Bool, constantName) {
-            // Intentionally left empty.
-        }
-                
-        bool BooleanConstantExpression::evaluateAsBool(Valuation const* valuation) const {
-            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
-            return valuation->getBooleanValue(this->getConstantName());
-        }
-        
-        void BooleanConstantExpression::accept(ExpressionVisitor* visitor) const {
-            visitor->visit(this);
-        }
-        
-        std::shared_ptr<BaseExpression const> BooleanConstantExpression::simplify() const {
-            return this->shared_from_this();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/storage/expressions/BooleanConstantExpression.h b/src/storage/expressions/BooleanConstantExpression.h
deleted file mode 100644
index dd204d7a5..000000000
--- a/src/storage/expressions/BooleanConstantExpression.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
-#define STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
-
-#include "src/storage/expressions/ConstantExpression.h"
-#include "src/utility/OsDetection.h"
-
-namespace storm {
-    namespace expressions {
-        class BooleanConstantExpression : public ConstantExpression {
-        public:
-            /*!
-             * Creates a boolean constant expression with the given constant name.
-             *
-             * @param constantName The name of the boolean constant associated with this expression.
-             */
-            BooleanConstantExpression(std::string const& constantName);
-            
-            // Instantiate constructors and assignments with their default implementations.
-            BooleanConstantExpression(BooleanConstantExpression const& other) = default;
-            BooleanConstantExpression& operator=(BooleanConstantExpression const& other) = default;
-#ifndef WINDOWS
-            BooleanConstantExpression(BooleanConstantExpression&&) = default;
-            BooleanConstantExpression& operator=(BooleanConstantExpression&&) = default;
-#endif
-            virtual ~BooleanConstantExpression() = default;
-            
-            // Override base class methods.
-            virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
-            virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::shared_ptr<BaseExpression const> simplify() const override;
-        };
-    }
-}
-
-#endif /* STORM_STORAGE_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/BooleanLiteralExpression.cpp b/src/storage/expressions/BooleanLiteralExpression.cpp
index b0a65594c..5112ec8a9 100644
--- a/src/storage/expressions/BooleanLiteralExpression.cpp
+++ b/src/storage/expressions/BooleanLiteralExpression.cpp
@@ -14,10 +14,6 @@ namespace storm {
             return true;
         }
         
-        bool BooleanLiteralExpression::hasConstantValue() const {
-            return true;
-        }
-        
         bool BooleanLiteralExpression::isTrue() const {
             return this->getValue() == true;
         }
@@ -30,10 +26,6 @@ namespace storm {
             return std::set<std::string>();
         }
         
-        std::set<std::string> BooleanLiteralExpression::getConstants() const {
-            return std::set<std::string>();
-        }
-        
         std::shared_ptr<BaseExpression const> BooleanLiteralExpression::simplify() const {
             return this->shared_from_this();
         }
diff --git a/src/storage/expressions/BooleanLiteralExpression.h b/src/storage/expressions/BooleanLiteralExpression.h
index 31a7d5dca..fc299e60a 100644
--- a/src/storage/expressions/BooleanLiteralExpression.h
+++ b/src/storage/expressions/BooleanLiteralExpression.h
@@ -27,11 +27,9 @@ namespace storm {
             // Override base class methods.
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual bool isLiteral() const override;
-            virtual bool hasConstantValue() const override;
             virtual bool isTrue() const override;
             virtual bool isFalse() const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
             
diff --git a/src/storage/expressions/ConstantExpression.cpp b/src/storage/expressions/ConstantExpression.cpp
deleted file mode 100644
index ec1efc11a..000000000
--- a/src/storage/expressions/ConstantExpression.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "src/storage/expressions/ConstantExpression.h"
-
-namespace storm {
-    namespace expressions {
-        ConstantExpression::ConstantExpression(ExpressionReturnType returnType, std::string const& constantName) : BaseExpression(returnType), constantName(constantName) {
-            // Intentionally left empty.
-        }
-        
-        std::set<std::string> ConstantExpression::getVariables() const {
-            return std::set<std::string>();
-        }
-        
-        std::set<std::string> ConstantExpression::getConstants() const {
-            return {this->getConstantName()};
-        }
-        
-        std::string const& ConstantExpression::getConstantName() const {
-            return this->constantName;
-        }
-        
-        bool ConstantExpression::isConstant() const {
-            return true;
-        }
-        
-        bool ConstantExpression::hasConstantValue() const {
-            return false;
-        }
-        
-        std::string const& ConstantExpression::getIdentifier() const {
-            return this->getConstantName();
-        }
-        
-        void ConstantExpression::printToStream(std::ostream& stream) const {
-            stream << this->getConstantName();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/storage/expressions/ConstantExpression.h b/src/storage/expressions/ConstantExpression.h
deleted file mode 100644
index fd79fd51e..000000000
--- a/src/storage/expressions/ConstantExpression.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_
-#define STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_
-
-#include "src/storage/expressions/BaseExpression.h"
-#include "src/utility/OsDetection.h"
-
-namespace storm {
-    namespace expressions {
-        class ConstantExpression : public BaseExpression {
-        public:
-            /*!
-             * Creates a constant expression with the given return type and constant name.
-             *
-             * @param returnType The return type of the expression.
-             * @param constantName The name of the constant associated with this expression.
-             */
-            ConstantExpression(ExpressionReturnType returnType, std::string const& constantName);
-            
-            // Instantiate constructors and assignments with their default implementations.
-            ConstantExpression(ConstantExpression const& other) = default;
-            ConstantExpression& operator=(ConstantExpression const& other) = default;
-#ifndef WINDOWS
-            ConstantExpression(ConstantExpression&&) = default;
-            ConstantExpression& operator=(ConstantExpression&&) = default;
-#endif
-            virtual ~ConstantExpression() = default;
-            
-            // Override base class methods.
-            virtual bool isConstant() const override;
-            virtual bool hasConstantValue() const override;
-            virtual std::string const& getIdentifier() const override;
-            virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
-            
-            /*!
-             * Retrieves the name of the constant.
-             *
-             * @return The name of the constant.
-             */
-            std::string const& getConstantName() const;
-
-        protected:
-            // Override base class method.
-            virtual void printToStream(std::ostream& stream) const override;
-            
-        private:
-            // The name of the constant.
-            std::string constantName;
-        };
-    }
-}
-
-#endif /* STORM_STORAGE_EXPRESSIONS_CONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/DoubleConstantExpression.cpp b/src/storage/expressions/DoubleConstantExpression.cpp
deleted file mode 100644
index e7d541975..000000000
--- a/src/storage/expressions/DoubleConstantExpression.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "src/storage/expressions/DoubleConstantExpression.h"
-#include "src/exceptions/ExceptionMacros.h"
-
-namespace storm {
-    namespace expressions {
-        DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::Double, constantName) {
-            // Intentionally left empty.
-        }
-        
-        double DoubleConstantExpression::evaluateAsDouble(Valuation const* valuation) const {
-            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
-            return valuation->getDoubleValue(this->getConstantName());
-        }
-        
-        std::shared_ptr<BaseExpression const> DoubleConstantExpression::simplify() const {
-            return this->shared_from_this();
-        }
-        
-        void DoubleConstantExpression::accept(ExpressionVisitor* visitor) const {
-            visitor->visit(this);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/storage/expressions/DoubleConstantExpression.h b/src/storage/expressions/DoubleConstantExpression.h
deleted file mode 100644
index b271bf6db..000000000
--- a/src/storage/expressions/DoubleConstantExpression.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
-#define STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
-
-#include "src/storage/expressions/ConstantExpression.h"
-#include "src/utility/OsDetection.h"
-
-namespace storm {
-    namespace expressions {
-        class DoubleConstantExpression : public ConstantExpression {
-        public:
-            /*!
-             * Creates a double constant expression with the given constant name.
-             *
-             * @param constantName The name of the double constant associated with this expression.
-             */
-            DoubleConstantExpression(std::string const& constantName);
-            
-            // Instantiate constructors and assignments with their default implementations.
-            DoubleConstantExpression(DoubleConstantExpression const& other) = default;
-            DoubleConstantExpression& operator=(DoubleConstantExpression const& other) = default;
-#ifndef WINDOWS
-            DoubleConstantExpression(DoubleConstantExpression&&) = default;
-            DoubleConstantExpression& operator=(DoubleConstantExpression&&) = default;
-#endif
-            virtual ~DoubleConstantExpression() = default;
-            
-            // Override base class methods.
-            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
-            virtual void accept(ExpressionVisitor* visitor) const override;
-            virtual std::shared_ptr<BaseExpression const> simplify() const override;
-        };
-    }
-}
-
-#endif /* STORM_STORAGE_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index a319c40d8..b780a8862 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -13,19 +13,11 @@ namespace storm {
         bool DoubleLiteralExpression::isLiteral() const {
             return true;
         }
-
-        bool DoubleLiteralExpression::hasConstantValue() const {
-            return true;
-        }
         
         std::set<std::string> DoubleLiteralExpression::getVariables() const {
             return std::set<std::string>();
         }
         
-        std::set<std::string> DoubleLiteralExpression::getConstants() const {
-            return std::set<std::string>();
-        }
-        
         std::shared_ptr<BaseExpression const> DoubleLiteralExpression::simplify() const {
             return this->shared_from_this();
         }
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index 5395a34a8..ad22ee3be 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -27,9 +27,7 @@ namespace storm {
             // Override base class methods.
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual bool isLiteral() const override;
-            virtual bool hasConstantValue() const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
 
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index ae787faed..863d630f3 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -5,23 +5,10 @@
 #include "src/storage/expressions/SubstitutionVisitor.h"
 #include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
 #include "src/storage/expressions/TypeCheckVisitor.h"
+#include "src/storage/expressions/Expressions.h"
 #include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/ExceptionMacros.h"
 
-#include "src/storage/expressions/IfThenElseExpression.h"
-#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
-#include "src/storage/expressions/BinaryRelationExpression.h"
-#include "src/storage/expressions/BooleanConstantExpression.h"
-#include "src/storage/expressions/IntegerConstantExpression.h"
-#include "src/storage/expressions/DoubleConstantExpression.h"
-#include "src/storage/expressions/BooleanLiteralExpression.h"
-#include "src/storage/expressions/IntegerLiteralExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
-#include "src/storage/expressions/VariableExpression.h"
-#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
-
 namespace storm {
     namespace expressions {
         Expression::Expression(std::shared_ptr<BaseExpression const> const& expressionPtr) : expressionPtr(expressionPtr) {
@@ -80,20 +67,12 @@ namespace storm {
             return this->getBaseExpression().getIdentifier();
         }
         
-        bool Expression::hasConstantValue() const {
-            return this->getBaseExpression().hasConstantValue();
-        }
-        
         bool Expression::containsVariables() const {
             return this->getBaseExpression().containsVariables();
         }
         
         bool Expression::isLiteral() const {
-            return this->isLiteral();
-        }
-        
-        bool Expression::isConstant() const {
-            return this->getBaseExpression().isConstant();
+            return this->getBaseExpression().isLiteral();
         }
         
         bool Expression::isVariable() const {
@@ -112,17 +91,6 @@ namespace storm {
             return this->getBaseExpression().getVariables();
         }
         
-        std::set<std::string> Expression::getConstants() const {
-            return this->getBaseExpression().getConstants();
-        }
-        
-        std::set<std::string> Expression::getIdentifiers() const {
-            std::set<std::string> result = this->getConstants();
-            std::set<std::string> variables = this->getVariables();
-            result.insert(variables.begin(), variables.end());
-            return result;
-        }
-        
         BaseExpression const& Expression::getBaseExpression() const {
             return *this->expressionPtr;
         }
@@ -179,18 +147,6 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new VariableExpression(ExpressionReturnType::Undefined, variableName)));
         }
         
-        Expression Expression::createBooleanConstant(std::string const& constantName) {
-            return Expression(std::shared_ptr<BaseExpression>(new BooleanConstantExpression(constantName)));
-        }
-        
-        Expression Expression::createIntegerConstant(std::string const& constantName) {
-            return Expression(std::shared_ptr<BaseExpression>(new IntegerConstantExpression(constantName)));
-        }
-        
-        Expression Expression::createDoubleConstant(std::string const& constantName) {
-            return Expression(std::shared_ptr<BaseExpression>(new DoubleConstantExpression(constantName)));
-        }
-        
         Expression Expression::operator+(Expression const& other) const {
             LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '+' requires numerical operands.");
             return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Plus)));
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 11636521b..bfa2dc4d8 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -39,9 +39,6 @@ namespace storm {
             static Expression createIntegerVariable(std::string const& variableName);
             static Expression createDoubleVariable(std::string const& variableName);
             static Expression createUndefinedVariable(std::string const& variableName);
-            static Expression createBooleanConstant(std::string const& constantName);
-            static Expression createIntegerConstant(std::string const& constantName);
-            static Expression createDoubleConstant(std::string const& constantName);
             
             // Provide operator overloads to conveniently construct new expressions from other expressions.
             Expression operator+(Expression const& other) const;
@@ -127,9 +124,8 @@ namespace storm {
             void check(std::unordered_map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const;
             
             /*!
-             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
-             * valuation and returns the resulting boolean value. If the return type of the expression is not a boolean
-             * an exception is thrown.
+             * Evaluates the expression under the valuation of variables given by the valuation and returns the
+             * resulting boolean value. If the return type of the expression is not a boolean an exception is thrown.
              *
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The boolean value of the expression under the given valuation.
@@ -137,9 +133,8 @@ namespace storm {
             bool evaluateAsBool(Valuation const* valuation = nullptr) const;
             
             /*!
-             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
-             * valuation and returns the resulting integer value. If the return type of the expression is not an integer
-             * an exception is thrown.
+             * Evaluates the expression under the valuation of variables given by the valuation and returns the
+             * resulting integer value. If the return type of the expression is not an integer an exception is thrown.
              *
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The integer value of the expression under the given valuation.
@@ -147,9 +142,8 @@ namespace storm {
             int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const;
             
             /*!
-             * Evaluates the expression under the valuation of unknowns (variables and constants) given by the
-             * valuation and returns the resulting double value. If the return type of the expression is not a double
-             * an exception is thrown.
+             * Evaluates the expression under the valuation of variables given by the valuation and returns the
+             * resulting double value. If the return type of the expression is not a double an exception is thrown.
              *
              * @param valuation The valuation of unknowns under which to evaluate the expression.
              * @return The double value of the expression under the given valuation.
@@ -180,19 +174,12 @@ namespace storm {
             
             /*!
              * Retrieves the identifier associated with this expression. This is only legal to call if the expression
-             * is either a constant or a variable.
+             * is a variable.
              *
              * @return The identifier associated with this expression.
              */
             virtual std::string const& getIdentifier() const;
             
-            /*!
-             * Retrieves whether the expression has a constant value, i.e., does not involve variables.
-             *
-             * @return True iff the expression has a constant value.
-             */
-            virtual bool hasConstantValue() const;
-            
             /*!
              * Retrieves whether the expression contains a variable.
              *
@@ -207,13 +194,6 @@ namespace storm {
              */
             virtual bool isLiteral() const;
             
-            /*!
-             * Retrieves whether the expression is a constant.
-             *
-             * @return True iff the expression is a constant.
-             */
-            virtual bool isConstant() const;
-            
             /*!
              * Retrieves whether the expression is a variable.
              *
@@ -242,20 +222,6 @@ namespace storm {
              */
             std::set<std::string> getVariables() const;
             
-            /*!
-             * Retrieves the set of all constants that appear in the expression.
-             *
-             * @return The set of all constants that appear in the expression.
-             */
-            std::set<std::string> getConstants() const;
-            
-            /*!
-             * Retrieves the set of all identifiers (constants and variables) that appear in the expression.
-             *
-             * @return The est of all identifiers that appear in the expression.
-             */
-            std::set<std::string> getIdentifiers() const;
-            
             /*!
              * Retrieves the base expression underlying this expression object. Note that prior to calling this, the
              * expression object must be properly initialized.
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index 928e6297c..1b417f6ed 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -8,10 +8,6 @@ namespace storm {
         class BinaryBooleanFunctionExpression;
         class BinaryNumericalFunctionExpression;
         class BinaryRelationExpression;
-        class BooleanConstantExpression;
-        class DoubleConstantExpression;
-        class IntegerConstantExpression;
-        class IntegerConstantExpression;
         class VariableExpression;
         class UnaryBooleanFunctionExpression;
         class UnaryNumericalFunctionExpression;
@@ -25,9 +21,6 @@ namespace storm {
             virtual void visit(BinaryBooleanFunctionExpression const* expression) = 0;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) = 0;
             virtual void visit(BinaryRelationExpression const* expression) = 0;
-            virtual void visit(BooleanConstantExpression const* expression) = 0;
-            virtual void visit(DoubleConstantExpression const* expression) = 0;
-            virtual void visit(IntegerConstantExpression const* expression) = 0;
             virtual void visit(VariableExpression const* expression) = 0;
             virtual void visit(UnaryBooleanFunctionExpression const* expression) = 0;
             virtual void visit(UnaryNumericalFunctionExpression const* expression) = 0;
diff --git a/src/storage/expressions/Expressions.h b/src/storage/expressions/Expressions.h
index df8bbd8ed..d670c29e3 100644
--- a/src/storage/expressions/Expressions.h
+++ b/src/storage/expressions/Expressions.h
@@ -2,12 +2,9 @@
 #include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/BinaryRelationExpression.h"
-#include "src/storage/expressions/BooleanConstantExpression.h"
 #include "src/storage/expressions/BooleanLiteralExpression.h"
-#include "src/storage/expressions/DoubleConstantExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
-#include "src/storage/expressions/IntegerConstantExpression.h"
 #include "src/storage/expressions/IntegerLiteralExpression.h"
+#include "src/storage/expressions/DoubleLiteralExpression.h"
 #include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
 #include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/VariableExpression.h"
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
index 1b058bed2..a2153af6d 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
@@ -3,20 +3,7 @@
 #include <string>
 
 #include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
-
-#include "src/storage/expressions/IfThenElseExpression.h"
-#include "src/storage/expressions/BinaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
-#include "src/storage/expressions/BinaryRelationExpression.h"
-#include "src/storage/expressions/BooleanConstantExpression.h"
-#include "src/storage/expressions/IntegerConstantExpression.h"
-#include "src/storage/expressions/DoubleConstantExpression.h"
-#include "src/storage/expressions/BooleanLiteralExpression.h"
-#include "src/storage/expressions/IntegerLiteralExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
-#include "src/storage/expressions/VariableExpression.h"
-#include "src/storage/expressions/UnaryBooleanFunctionExpression.h"
-#include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
+#include "src/storage/expressions/Expressions.h"
 
 namespace storm {
     namespace expressions  {
@@ -106,40 +93,7 @@ namespace storm {
                 this->expressionStack.push(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getRelationType())));
             }
         }
-        
-        template<typename MapType>
-        void IdentifierSubstitutionVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
-            // If the boolean constant is in the key set of the substitution, we need to replace it.
-            auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
-            if (namePair != this->identifierToIdentifierMap.end()) {
-                this->expressionStack.push(std::shared_ptr<BaseExpression>(new BooleanConstantExpression(namePair->second)));
-            } else {
-                this->expressionStack.push(expression->getSharedPointer());
-            }
-        }
-        
-        template<typename MapType>
-        void IdentifierSubstitutionVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
-            // If the double constant is in the key set of the substitution, we need to replace it.
-            auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
-            if (namePair != this->identifierToIdentifierMap.end()) {
-                this->expressionStack.push(std::shared_ptr<BaseExpression>(new DoubleConstantExpression(namePair->second)));
-            } else {
-                this->expressionStack.push(expression->getSharedPointer());
-            }
-        }
-        
-        template<typename MapType>
-        void IdentifierSubstitutionVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
-            // If the integer constant is in the key set of the substitution, we need to replace it.
-            auto const& namePair = this->identifierToIdentifierMap.find(expression->getConstantName());
-            if (namePair != this->identifierToIdentifierMap.end()) {
-                this->expressionStack.push(std::shared_ptr<BaseExpression>(new IntegerConstantExpression(namePair->second)));
-            } else {
-                this->expressionStack.push(expression->getSharedPointer());
-            }
-        }
-        
+                
         template<typename MapType>
         void IdentifierSubstitutionVisitor<MapType>::visit(VariableExpression const* expression) {
             // If the variable is in the key set of the substitution, we need to replace it.
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.h b/src/storage/expressions/IdentifierSubstitutionVisitor.h
index e8412d949..23dae79de 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.h
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.h
@@ -32,9 +32,6 @@ namespace storm {
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
             virtual void visit(BinaryRelationExpression const* expression) override;
-            virtual void visit(BooleanConstantExpression const* expression) override;
-            virtual void visit(DoubleConstantExpression const* expression) override;
-            virtual void visit(IntegerConstantExpression const* expression) override;
             virtual void visit(VariableExpression const* expression) override;
             virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
             virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
diff --git a/src/storage/expressions/IfThenElseExpression.cpp b/src/storage/expressions/IfThenElseExpression.cpp
index 81ebca670..4cc028b3c 100644
--- a/src/storage/expressions/IfThenElseExpression.cpp
+++ b/src/storage/expressions/IfThenElseExpression.cpp
@@ -33,10 +33,6 @@ namespace storm {
             }
         }
         
-        bool IfThenElseExpression::isConstant() const {
-            return this->condition->isConstant() && this->thenExpression->isConstant() && this->elseExpression->isConstant();
-        }
-        
         std::set<std::string> IfThenElseExpression::getVariables() const {
             std::set<std::string> result = this->condition->getVariables();
             std::set<std::string> tmp = this->thenExpression->getVariables();
@@ -46,15 +42,6 @@ namespace storm {
             return result;
         }
         
-        std::set<std::string> IfThenElseExpression::getConstants() const {
-            std::set<std::string> result = this->condition->getConstants();
-            std::set<std::string> tmp = this->thenExpression->getConstants();
-            result.insert(tmp.begin(), tmp.end());
-            tmp = this->elseExpression->getConstants();
-            result.insert(tmp.begin(), tmp.end());
-            return result;
-        }
-        
         std::shared_ptr<BaseExpression const> IfThenElseExpression::simplify() const {
             std::shared_ptr<BaseExpression const> conditionSimplified;
             if (conditionSimplified->isTrue()) {
diff --git a/src/storage/expressions/IfThenElseExpression.h b/src/storage/expressions/IfThenElseExpression.h
index 979cb08f0..b44de20be 100644
--- a/src/storage/expressions/IfThenElseExpression.h
+++ b/src/storage/expressions/IfThenElseExpression.h
@@ -30,9 +30,7 @@ namespace storm {
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
-            virtual bool isConstant() const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
             
diff --git a/src/storage/expressions/IntegerConstantExpression.cpp b/src/storage/expressions/IntegerConstantExpression.cpp
deleted file mode 100644
index 60ad8de89..000000000
--- a/src/storage/expressions/IntegerConstantExpression.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "src/storage/expressions/IntegerConstantExpression.h"
-#include "src/exceptions/ExceptionMacros.h"
-
-namespace storm {
-    namespace expressions {
-        IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(ExpressionReturnType::Int, constantName) {
-            // Intentionally left empty.
-        }
-        
-        int_fast64_t IntegerConstantExpression::evaluateAsInt(Valuation const* valuation) const {
-            LOG_ASSERT(valuation != nullptr, "Evaluating expressions with unknowns without valuation.");
-            return valuation->getIntegerValue(this->getConstantName());
-        }
-        
-        double IntegerConstantExpression::evaluateAsDouble(Valuation const* valuation) const {
-            return static_cast<double>(this->evaluateAsInt(valuation));
-        }
-        
-        std::shared_ptr<BaseExpression const> IntegerConstantExpression::simplify() const {
-            return this->shared_from_this();
-        }
-        
-        void IntegerConstantExpression::accept(ExpressionVisitor* visitor) const {
-            visitor->visit(this);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/storage/expressions/IntegerConstantExpression.h b/src/storage/expressions/IntegerConstantExpression.h
deleted file mode 100644
index fcf151ead..000000000
--- a/src/storage/expressions/IntegerConstantExpression.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
-#define STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
-
-#include "src/storage/expressions/ConstantExpression.h"
-#include "src/utility/OsDetection.h"
-
-namespace storm {
-    namespace expressions {
-        class IntegerConstantExpression : public ConstantExpression {
-        public:
-            /*!
-             * Creates an integer constant expression with the given constant name.
-             *
-             * @param constantName The name of the integer constant associated with this expression.
-             */
-            IntegerConstantExpression(std::string const& constantName);
-            
-            // Instantiate constructors and assignments with their default implementations.
-            IntegerConstantExpression(IntegerConstantExpression const& other) = default;
-            IntegerConstantExpression& operator=(IntegerConstantExpression const& other) = default;
-#ifndef WINDOWS
-            IntegerConstantExpression(IntegerConstantExpression&&) = default;
-            IntegerConstantExpression& operator=(IntegerConstantExpression&&) = default;
-#endif
-            virtual ~IntegerConstantExpression() = default;
-            
-            // Override base class methods.
-            virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
-            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
-            virtual std::shared_ptr<BaseExpression const> simplify() const override;
-            virtual void accept(ExpressionVisitor* visitor) const;
-        };
-    }
-}
-
-#endif /* STORM_STORAGE_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ */
diff --git a/src/storage/expressions/IntegerLiteralExpression.cpp b/src/storage/expressions/IntegerLiteralExpression.cpp
index 5bdb9c1a9..47341a771 100644
--- a/src/storage/expressions/IntegerLiteralExpression.cpp
+++ b/src/storage/expressions/IntegerLiteralExpression.cpp
@@ -18,18 +18,10 @@ namespace storm {
             return true;
         }
         
-        bool IntegerLiteralExpression::hasConstantValue() const {
-            return true;
-        }
-        
         std::set<std::string> IntegerLiteralExpression::getVariables() const {
             return std::set<std::string>();
         }
         
-        std::set<std::string> IntegerLiteralExpression::getConstants() const {
-            return std::set<std::string>();
-        }
-        
         std::shared_ptr<BaseExpression const> IntegerLiteralExpression::simplify() const {
             return this->shared_from_this();
         }
diff --git a/src/storage/expressions/IntegerLiteralExpression.h b/src/storage/expressions/IntegerLiteralExpression.h
index 2a45eb5cc..4a9e8882f 100644
--- a/src/storage/expressions/IntegerLiteralExpression.h
+++ b/src/storage/expressions/IntegerLiteralExpression.h
@@ -28,9 +28,7 @@ namespace storm {
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual bool isLiteral() const override;
-            virtual bool hasConstantValue() const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
             
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index 7990ab4f9..2559b474b 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -94,39 +94,6 @@ namespace storm {
             }
         }
         
-		template<typename MapType>
-        void SubstitutionVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
-            // If the boolean constant is in the key set of the substitution, we need to replace it.
-            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
-            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
-                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
-            } else {
-                this->expressionStack.push(expression->getSharedPointer());
-            }
-        }
-        
-		template<typename MapType>
-        void SubstitutionVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
-            // If the double constant is in the key set of the substitution, we need to replace it.
-            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
-            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
-                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
-            } else {
-                this->expressionStack.push(expression->getSharedPointer());
-            }
-        }
-        
-		template<typename MapType>
-        void SubstitutionVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
-            // If the integer constant is in the key set of the substitution, we need to replace it.
-            auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName());
-            if (nameExpressionPair != this->identifierToExpressionMap.end()) {
-                this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer());
-            } else {
-                this->expressionStack.push(expression->getSharedPointer());
-            }
-        }
-        
 		template<typename MapType>
         void SubstitutionVisitor<MapType>::visit(VariableExpression const* expression) {
             // If the variable is in the key set of the substitution, we need to replace it.
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index d46d62cee..bc58148e3 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -32,9 +32,6 @@ namespace storm {
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
             virtual void visit(BinaryRelationExpression const* expression) override;
-            virtual void visit(BooleanConstantExpression const* expression) override;
-            virtual void visit(DoubleConstantExpression const* expression) override;
-            virtual void visit(IntegerConstantExpression const* expression) override;
             virtual void visit(VariableExpression const* expression) override;
             virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
             virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
diff --git a/src/storage/expressions/TypeCheckVisitor.cpp b/src/storage/expressions/TypeCheckVisitor.cpp
index d5cef0381..044b85237 100644
--- a/src/storage/expressions/TypeCheckVisitor.cpp
+++ b/src/storage/expressions/TypeCheckVisitor.cpp
@@ -40,28 +40,7 @@ namespace storm {
             expression->getFirstOperand()->accept(this);
             expression->getSecondOperand()->accept(this);
         }
-        
-        template<typename MapType>
-        void TypeCheckVisitor<MapType>::visit(BooleanConstantExpression const* expression) {
-            auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
-            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Bool, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected 'bool', but found '" << expression->getReturnType() << "'.");
-        }
-        
-        template<typename MapType>
-        void TypeCheckVisitor<MapType>::visit(DoubleConstantExpression const* expression) {
-            auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
-            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Double, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected 'double', but found '" << expression->getReturnType() << "'.");
-        }
-        
-        template<typename MapType>
-        void TypeCheckVisitor<MapType>::visit(IntegerConstantExpression const* expression) {
-            auto identifierTypePair = this->identifierToTypeMap.find(expression->getConstantName());
-            LOG_THROW(identifierTypePair != this->identifierToTypeMap.end(), storm::exceptions::InvalidArgumentException, "No type available for identifier '" << expression->getConstantName() << "'.");
-            LOG_THROW(identifierTypePair->second == ExpressionReturnType::Int, storm::exceptions::InvalidTypeException, "Type mismatch for constant '" << expression->getConstantName() << "': expected 'int', but found '" << expression->getReturnType() << "'.");
-        }
-        
+                
         template<typename MapType>
         void TypeCheckVisitor<MapType>::visit(VariableExpression const* expression) {
             auto identifierTypePair = this->identifierToTypeMap.find(expression->getVariableName());
diff --git a/src/storage/expressions/TypeCheckVisitor.h b/src/storage/expressions/TypeCheckVisitor.h
index e39a536a6..7772e0e7e 100644
--- a/src/storage/expressions/TypeCheckVisitor.h
+++ b/src/storage/expressions/TypeCheckVisitor.h
@@ -30,9 +30,6 @@ namespace storm {
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
             virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
             virtual void visit(BinaryRelationExpression const* expression) override;
-            virtual void visit(BooleanConstantExpression const* expression) override;
-            virtual void visit(DoubleConstantExpression const* expression) override;
-            virtual void visit(IntegerConstantExpression const* expression) override;
             virtual void visit(VariableExpression const* expression) override;
             virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
             virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp
index 8349a8aac..62ff442ed 100644
--- a/src/storage/expressions/UnaryExpression.cpp
+++ b/src/storage/expressions/UnaryExpression.cpp
@@ -13,18 +13,10 @@ namespace storm {
             return this->getOperand()->containsVariables();
         }
         
-        bool UnaryExpression::hasConstantValue() const {
-            return this->getOperand()->hasConstantValue();
-        }
-        
         std::set<std::string> UnaryExpression::getVariables() const {
             return this->getOperand()->getVariables();
         }
         
-        std::set<std::string> UnaryExpression::getConstants() const {
-            return this->getOperand()->getVariables();
-        }
-        
         std::shared_ptr<BaseExpression const> const& UnaryExpression::getOperand() const {
             return this->operand;
         }
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
index e071aa979..8ad304ce1 100644
--- a/src/storage/expressions/UnaryExpression.h
+++ b/src/storage/expressions/UnaryExpression.h
@@ -27,11 +27,9 @@ namespace storm {
             
             // Override base class methods.
             virtual bool containsVariables() const override;
-            virtual bool hasConstantValue() const override;
             virtual uint_fast64_t getArity() const override;
             virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             
             /*!
              * Retrieves the operand of the unary expression.
diff --git a/src/storage/expressions/VariableExpression.cpp b/src/storage/expressions/VariableExpression.cpp
index 88cb7ba86..2062c58ee 100644
--- a/src/storage/expressions/VariableExpression.cpp
+++ b/src/storage/expressions/VariableExpression.cpp
@@ -53,10 +53,6 @@ namespace storm {
             return {this->getVariableName()};
         }
         
-        std::set<std::string> VariableExpression::getConstants() const {
-            return std::set<std::string>();
-        }
-        
         std::shared_ptr<BaseExpression const> VariableExpression::simplify() const {
             return this->shared_from_this();
         }
diff --git a/src/storage/expressions/VariableExpression.h b/src/storage/expressions/VariableExpression.h
index e6d9366f7..6eff8c794 100644
--- a/src/storage/expressions/VariableExpression.h
+++ b/src/storage/expressions/VariableExpression.h
@@ -32,7 +32,6 @@ namespace storm {
             virtual std::string const& getIdentifier() const override;
             virtual bool containsVariables() const override;
             virtual std::set<std::string> getVariables() const override;
-            virtual std::set<std::string> getConstants() const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
 
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index c29001b16..10a1114e6 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -343,11 +343,9 @@ namespace storm {
                 
                 // Check defining expressions of defined constants.
                 if (constant.isDefined()) {
-                    LOG_THROW(constant.getExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": definition of constant " << constant.getName() << " must not refer to variables.");
-                    
-                    std::set<std::string> containedConstantNames = constant.getExpression().getConstants();
-                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstantNames.begin(), containedConstantNames.end());
-                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": defining expression refers to unknown constants.");
+                    std::set<std::string> containedIdentifiers = constant.getExpression().getVariables();
+                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                    LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << constant.getFilename() << ", line " << constant.getLineNumber() << ": defining expression refers to unknown identifiers.");
                     
                     // Now check that the constants appear with the right types.
                     try {
@@ -373,12 +371,11 @@ namespace storm {
                 LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
                 
                 // Check the initial value of the variable.
-                LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
-                std::set<std::string> containedConstants = variable.getInitialValueExpression().getConstants();
-                bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                std::set<std::string> containedIdentifiers = variable.getInitialValueExpression().getVariables();
+                bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
                 try {
-                variable.getInitialValueExpression().check(identifierToTypeMap);
+                    variable.getInitialValueExpression().check(identifierToTypeMap);
                 } catch (storm::exceptions::InvalidTypeException const& e) {
                     LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
                 }
@@ -396,9 +393,8 @@ namespace storm {
                 LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
                 
                 // Check that bound expressions of the range.
-                LOG_THROW(variable.getLowerBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression must not refer to variables.");
-                std::set<std::string> containedConstants = variable.getLowerBoundExpression().getConstants();
-                bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                std::set<std::string> containedIdentifiers = variable.getLowerBoundExpression().getVariables();
+                bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression refers to unknown constants.");
                 try {
                     variable.getLowerBoundExpression().check(identifierToTypeMap);
@@ -406,9 +402,8 @@ namespace storm {
                     LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
                 }
 
-                LOG_THROW(variable.getUpperBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression must not refer to variables.");
-                containedConstants = variable.getLowerBoundExpression().getConstants();
-                isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                containedIdentifiers = variable.getLowerBoundExpression().getVariables();
+                isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants.");
                 try {
                     variable.getUpperBoundExpression().check(identifierToTypeMap);
@@ -417,9 +412,8 @@ namespace storm {
                 }
                 
                 // Check the initial value of the variable.
-                LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
-                containedConstants = variable.getInitialValueExpression().getConstants();
-                isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                containedIdentifiers = variable.getInitialValueExpression().getVariables();
+                isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
                 try {
                     variable.getInitialValueExpression().check(identifierToTypeMap);
@@ -443,9 +437,8 @@ namespace storm {
                     LOG_THROW(allIdentifiers.find(variable.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": duplicate identifier '" << variable.getName() << "'.");
                     
                     // Check the initial value of the variable.
-                    LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
-                    std::set<std::string> containedConstants = variable.getInitialValueExpression().getConstants();
-                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    std::set<std::string> containedIdentifiers = variable.getInitialValueExpression().getVariables();
+                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
                     try {
                         variable.getInitialValueExpression().check(identifierToTypeMap);
@@ -468,9 +461,8 @@ namespace storm {
                     identifierToTypeMap.emplace(variable.getName(), storm::expressions::ExpressionReturnType::Int);
                     
                     // Check that bound expressions of the range.
-                    LOG_THROW(variable.getLowerBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression must not refer to variables.");
-                    std::set<std::string> containedConstants = variable.getLowerBoundExpression().getConstants();
-                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    std::set<std::string> containedIdentifiers = variable.getLowerBoundExpression().getVariables();
+                    bool isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": lower bound expression refers to unknown constants.");
                     try {
                         variable.getLowerBoundExpression().check(identifierToTypeMap);
@@ -478,9 +470,8 @@ namespace storm {
                         LOG_THROW(false, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": " << e.what());
                     }
 
-                    LOG_THROW(variable.getUpperBoundExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression must not refer to variables.");
-                    containedConstants = variable.getLowerBoundExpression().getConstants();
-                    isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    containedIdentifiers = variable.getLowerBoundExpression().getVariables();
+                    isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants.");
                     try {
                         variable.getUpperBoundExpression().check(identifierToTypeMap);
@@ -489,9 +480,8 @@ namespace storm {
                     }
                     
                     // Check the initial value of the variable.
-                    LOG_THROW(variable.getInitialValueExpression().getVariables().empty(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression must not refer to variables.");
-                    containedConstants = variable.getInitialValueExpression().getConstants();
-                    isValid = std::includes(constantNames.begin(), constantNames.end(), containedConstants.begin(), containedConstants.end());
+                    containedIdentifiers = variable.getInitialValueExpression().getVariables();
+                    isValid = std::includes(constantNames.begin(), constantNames.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants.");
                     try {
                         variable.getInitialValueExpression().check(identifierToTypeMap);
@@ -521,7 +511,7 @@ namespace storm {
                 
                 for (auto const& command : module.getCommands()) {
                     // Check the guard.
-                    std::set<std::string> containedIdentifiers = command.getGuardExpression().getIdentifiers();
+                    std::set<std::string> containedIdentifiers = command.getGuardExpression().getVariables();
                     bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": guard refers to unknown identifiers.");
                     try {
@@ -533,7 +523,7 @@ namespace storm {
                     
                     // Check all updates.
                     for (auto const& update : command.getUpdates()) {
-                        containedIdentifiers = update.getLikelihoodExpression().getIdentifiers();
+                        containedIdentifiers = update.getLikelihoodExpression().getVariables();
                         isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                         LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": likelihood expression refers to unknown identifiers.");
                         try {
@@ -556,7 +546,7 @@ namespace storm {
                             auto variableTypePair = identifierToTypeMap.find(assignment.getVariableName());
                             LOG_THROW(variableTypePair->second == assignment.getExpression().getReturnType(), storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": illegally assigning a value of type '" << assignment.getExpression().getReturnType() << "' to variable '" << variableTypePair->first << "' of type '" << variableTypePair->second << "'.");
                             
-                            containedIdentifiers = assignment.getExpression().getIdentifiers();
+                            containedIdentifiers = assignment.getExpression().getVariables();
                             isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                             LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << command.getFilename() << ", line " << command.getLineNumber() << ": likelihood expression refers to unknown identifiers.");
                             try {
@@ -575,7 +565,7 @@ namespace storm {
             // Now check the reward models.
             for (auto const& rewardModel : this->getRewardModels()) {
                 for (auto const& stateReward : rewardModel.getStateRewards()) {
-                    std::set<std::string> containedIdentifiers = stateReward.getStatePredicateExpression().getIdentifiers();
+                    std::set<std::string> containedIdentifiers = stateReward.getStatePredicateExpression().getVariables();
                     bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": state reward expression refers to unknown identifiers.");
                     try {
@@ -585,7 +575,7 @@ namespace storm {
                     }
                     LOG_THROW(stateReward.getStatePredicateExpression().hasBooleanReturnType(), storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": state predicate must evaluate to type 'bool'.");
                     
-                    containedIdentifiers = stateReward.getRewardValueExpression().getIdentifiers();
+                    containedIdentifiers = stateReward.getRewardValueExpression().getVariables();
                     isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << stateReward.getFilename() << ", line " << stateReward.getLineNumber() << ": state reward value expression refers to unknown identifiers.");
                     try {
@@ -597,7 +587,7 @@ namespace storm {
                 }
                 
                 for (auto const& transitionReward : rewardModel.getTransitionRewards()) {
-                    std::set<std::string> containedIdentifiers = transitionReward.getStatePredicateExpression().getIdentifiers();
+                    std::set<std::string> containedIdentifiers = transitionReward.getStatePredicateExpression().getVariables();
                     bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": state reward expression refers to unknown identifiers.");
                     try {
@@ -607,7 +597,7 @@ namespace storm {
                     }
                     LOG_THROW(transitionReward.getStatePredicateExpression().hasBooleanReturnType(), storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": state predicate must evaluate to type 'bool'.");
                     
-                    containedIdentifiers = transitionReward.getRewardValueExpression().getIdentifiers();
+                    containedIdentifiers = transitionReward.getRewardValueExpression().getVariables();
                     isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                     LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << transitionReward.getFilename() << ", line " << transitionReward.getLineNumber() << ": state reward value expression refers to unknown identifiers.");
                     try {
@@ -620,7 +610,7 @@ namespace storm {
             }
             
             // Check the initial states expression.
-            std::set<std::string> containedIdentifiers = this->getInitialConstruct().getInitialStatesExpression().getIdentifiers();
+            std::set<std::string> containedIdentifiers = this->getInitialConstruct().getInitialStatesExpression().getVariables();
             bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
             LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << this->getInitialConstruct().getFilename() << ", line " << this->getInitialConstruct().getLineNumber() << ": initial expression refers to unknown identifiers.");
             try {
@@ -634,7 +624,7 @@ namespace storm {
                 // Check for duplicate identifiers.
                 LOG_THROW(allIdentifiers.find(label.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": duplicate identifier '" << label.getName() << "'.");
                 
-                std::set<std::string> containedIdentifiers = label.getStatePredicateExpression().getIdentifiers();
+                std::set<std::string> containedIdentifiers = label.getStatePredicateExpression().getVariables();
                 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << label.getFilename() << ", line " << label.getLineNumber() << ": label expression refers to unknown identifiers.");
                 try {
@@ -651,7 +641,7 @@ namespace storm {
                 // Check for duplicate identifiers.
                 LOG_THROW(allIdentifiers.find(formula.getName()) == allIdentifiers.end(), storm::exceptions::WrongFormatException, "Error in " << formula.getFilename() << ", line " << formula.getLineNumber() << ": duplicate identifier '" << formula.getName() << "'.");
                 
-                std::set<std::string> containedIdentifiers = formula.getExpression().getIdentifiers();
+                std::set<std::string> containedIdentifiers = formula.getExpression().getVariables();
                 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
                 LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << formula.getFilename() << ", line " << formula.getLineNumber() << ": formula expression refers to unknown identifiers.");
                 try {
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 893149a23..26822190d 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -15,9 +15,6 @@ TEST(Expression, FactoryMethodTest) {
     EXPECT_NO_THROW(storm::expressions::Expression::createBooleanVariable("x"));
     EXPECT_NO_THROW(storm::expressions::Expression::createIntegerVariable("y"));
     EXPECT_NO_THROW(storm::expressions::Expression::createDoubleVariable("z"));
-    EXPECT_NO_THROW(storm::expressions::Expression::createBooleanConstant("a"));
-    EXPECT_NO_THROW(storm::expressions::Expression::createIntegerConstant("b"));
-    EXPECT_NO_THROW(storm::expressions::Expression::createDoubleConstant("c"));
 }
 
 TEST(Expression, AccessorTest) {
@@ -28,9 +25,6 @@ TEST(Expression, AccessorTest) {
     storm::expressions::Expression boolVarExpression;
     storm::expressions::Expression intVarExpression;
     storm::expressions::Expression doubleVarExpression;
-    storm::expressions::Expression boolConstExpression;
-    storm::expressions::Expression intConstExpression;
-    storm::expressions::Expression doubleConstExpression;
     
     ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
     ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
@@ -39,79 +33,48 @@ TEST(Expression, AccessorTest) {
     ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
     ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
     ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
-    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
-    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
-    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
     
     EXPECT_TRUE(trueExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_TRUE(trueExpression.hasConstantValue());
+    EXPECT_TRUE(trueExpression.isLiteral());
     EXPECT_TRUE(trueExpression.isTrue());
     EXPECT_FALSE(trueExpression.isFalse());
     EXPECT_TRUE(trueExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(trueExpression.getConstants() == std::set<std::string>());
     
     EXPECT_TRUE(falseExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_TRUE(falseExpression.hasConstantValue());
+    EXPECT_TRUE(falseExpression.isLiteral());
     EXPECT_FALSE(falseExpression.isTrue());
     EXPECT_TRUE(falseExpression.isFalse());
     EXPECT_TRUE(falseExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(falseExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(threeExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    EXPECT_TRUE(threeExpression.hasConstantValue());
+    EXPECT_TRUE(threeExpression.isLiteral());
     EXPECT_FALSE(threeExpression.isTrue());
     EXPECT_FALSE(threeExpression.isFalse());
     EXPECT_TRUE(threeExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(threeExpression.getConstants() == std::set<std::string>());
     
     EXPECT_TRUE(piExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    EXPECT_TRUE(piExpression.hasConstantValue());
+    EXPECT_TRUE(piExpression.isLiteral());
     EXPECT_FALSE(piExpression.isTrue());
     EXPECT_FALSE(piExpression.isFalse());
     EXPECT_TRUE(piExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(piExpression.getConstants() == std::set<std::string>());
     
     EXPECT_TRUE(boolVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_FALSE(boolVarExpression.hasConstantValue());
+    EXPECT_FALSE(boolVarExpression.isLiteral());
     EXPECT_FALSE(boolVarExpression.isTrue());
     EXPECT_FALSE(boolVarExpression.isFalse());
     EXPECT_TRUE(boolVarExpression.getVariables() == std::set<std::string>({"x"}));
-    EXPECT_TRUE(boolVarExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(intVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    EXPECT_FALSE(intVarExpression.hasConstantValue());
+    EXPECT_FALSE(intVarExpression.isLiteral());
     EXPECT_FALSE(intVarExpression.isTrue());
     EXPECT_FALSE(intVarExpression.isFalse());
     EXPECT_TRUE(intVarExpression.getVariables() == std::set<std::string>({"y"}));
-    EXPECT_TRUE(intVarExpression.getConstants() == std::set<std::string>());
 
     EXPECT_TRUE(doubleVarExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    EXPECT_FALSE(doubleVarExpression.hasConstantValue());
+    EXPECT_FALSE(doubleVarExpression.isLiteral());
     EXPECT_FALSE(doubleVarExpression.isTrue());
     EXPECT_FALSE(doubleVarExpression.isFalse());
     EXPECT_TRUE(doubleVarExpression.getVariables() == std::set<std::string>({"z"}));
-    EXPECT_TRUE(doubleVarExpression.getConstants() == std::set<std::string>());
-
-    EXPECT_TRUE(boolConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    EXPECT_FALSE(boolConstExpression.hasConstantValue());
-    EXPECT_FALSE(boolConstExpression.isTrue());
-    EXPECT_FALSE(boolConstExpression.isFalse());
-    EXPECT_TRUE(boolConstExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(boolConstExpression.getConstants() == std::set<std::string>({"a"}));
-    
-    EXPECT_TRUE(intConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    EXPECT_FALSE(intConstExpression.hasConstantValue());
-    EXPECT_FALSE(intConstExpression.isTrue());
-    EXPECT_FALSE(intConstExpression.isFalse());
-    EXPECT_TRUE(intConstExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(intConstExpression.getConstants() == std::set<std::string>({"b"}));
-
-    EXPECT_TRUE(doubleConstExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    EXPECT_FALSE(doubleConstExpression.hasConstantValue());
-    EXPECT_FALSE(doubleConstExpression.isTrue());
-    EXPECT_FALSE(doubleConstExpression.isFalse());
-    EXPECT_TRUE(doubleConstExpression.getVariables() == std::set<std::string>());
-    EXPECT_TRUE(doubleConstExpression.getConstants() == std::set<std::string>({"c"}));
 }
 
 TEST(Expression, OperatorTest) {
@@ -122,9 +85,6 @@ TEST(Expression, OperatorTest) {
     storm::expressions::Expression boolVarExpression;
     storm::expressions::Expression intVarExpression;
     storm::expressions::Expression doubleVarExpression;
-    storm::expressions::Expression boolConstExpression;
-    storm::expressions::Expression intConstExpression;
-    storm::expressions::Expression doubleConstExpression;
     
     ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
     ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
@@ -133,18 +93,15 @@ TEST(Expression, OperatorTest) {
     ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
     ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
     ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
-    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
-    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
-    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
     
     storm::expressions::Expression tempExpression;
 
     ASSERT_THROW(tempExpression = trueExpression.ite(falseExpression, piExpression), storm::exceptions::InvalidTypeException);
-    ASSERT_NO_THROW(tempExpression = boolConstExpression.ite(threeExpression, doubleVarExpression));
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.ite(threeExpression, doubleVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    ASSERT_NO_THROW(tempExpression = boolConstExpression.ite(threeExpression, intVarExpression));
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.ite(threeExpression, intVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    ASSERT_NO_THROW(tempExpression = boolConstExpression.ite(trueExpression, falseExpression));
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.ite(trueExpression, falseExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression + piExpression, storm::exceptions::InvalidTypeException);
@@ -152,7 +109,7 @@ TEST(Expression, OperatorTest) {
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
     ASSERT_NO_THROW(tempExpression = threeExpression + piExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    ASSERT_NO_THROW(tempExpression = doubleVarExpression + doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression + doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
     
     ASSERT_THROW(tempExpression = trueExpression - piExpression, storm::exceptions::InvalidTypeException);
@@ -160,7 +117,7 @@ TEST(Expression, OperatorTest) {
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
     ASSERT_NO_THROW(tempExpression = threeExpression - piExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    ASSERT_NO_THROW(tempExpression = doubleVarExpression - doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression - doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
     
     ASSERT_THROW(tempExpression = -trueExpression, storm::exceptions::InvalidTypeException);
@@ -176,7 +133,7 @@ TEST(Expression, OperatorTest) {
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
     ASSERT_NO_THROW(tempExpression = threeExpression * piExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    ASSERT_NO_THROW(tempExpression = intVarExpression * intConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression * intVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
 
     ASSERT_THROW(tempExpression = trueExpression / piExpression, storm::exceptions::InvalidTypeException);
@@ -184,19 +141,19 @@ TEST(Expression, OperatorTest) {
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
     ASSERT_NO_THROW(tempExpression = threeExpression / piExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
-    ASSERT_NO_THROW(tempExpression = doubleVarExpression / intConstExpression);
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression / intVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
 
     ASSERT_THROW(tempExpression = trueExpression && piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = trueExpression && falseExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = boolVarExpression && boolConstExpression);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression && boolVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
 
     ASSERT_THROW(tempExpression = trueExpression || piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = trueExpression || falseExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = boolVarExpression || boolConstExpression);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression || boolVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
 
     ASSERT_THROW(tempExpression = !threeExpression, storm::exceptions::InvalidTypeException);
@@ -208,79 +165,79 @@ TEST(Expression, OperatorTest) {
     ASSERT_THROW(tempExpression = trueExpression == piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression == threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = intVarExpression == doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression == doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
 
     ASSERT_THROW(tempExpression = trueExpression != piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression != threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = intVarExpression != doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression != doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
 
     ASSERT_THROW(tempExpression = trueExpression > piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression > threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = intVarExpression > doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression > doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression >= piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression >= threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = intVarExpression >= doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression >= doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression < piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression < threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = intVarExpression < doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression < doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression <= piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression <= threeExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = intVarExpression <= doubleConstExpression);
+    ASSERT_NO_THROW(tempExpression = intVarExpression <= doubleVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = storm::expressions::Expression::minimum(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::minimum(threeExpression, threeExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::minimum(intVarExpression, doubleConstExpression));
+    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::minimum(intVarExpression, doubleVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
 
     ASSERT_THROW(tempExpression = storm::expressions::Expression::maximum(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::maximum(threeExpression, threeExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::maximum(intVarExpression, doubleConstExpression));
+    ASSERT_NO_THROW(tempExpression = storm::expressions::Expression::maximum(intVarExpression, doubleVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
     
     ASSERT_THROW(tempExpression = trueExpression.implies(piExpression), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = trueExpression.implies(falseExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = boolVarExpression.implies(boolConstExpression));
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.implies(boolVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression.iff(piExpression), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = trueExpression.iff(falseExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = boolVarExpression.iff(boolConstExpression));
+    ASSERT_NO_THROW(tempExpression = boolVarExpression.iff(boolVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = trueExpression ^ falseExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = boolVarExpression ^ boolConstExpression);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression ^ boolVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression.floor(), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression.floor());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    ASSERT_NO_THROW(tempExpression = doubleConstExpression.floor());
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression.floor());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
 
     ASSERT_THROW(tempExpression = trueExpression.ceil(), storm::exceptions::InvalidTypeException);
     ASSERT_NO_THROW(tempExpression = threeExpression.ceil());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
-    ASSERT_NO_THROW(tempExpression = doubleConstExpression.ceil());
+    ASSERT_NO_THROW(tempExpression = doubleVarExpression.ceil());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
 }
 
@@ -292,9 +249,6 @@ TEST(Expression, SubstitutionTest) {
     storm::expressions::Expression boolVarExpression;
     storm::expressions::Expression intVarExpression;
     storm::expressions::Expression doubleVarExpression;
-    storm::expressions::Expression boolConstExpression;
-    storm::expressions::Expression intConstExpression;
-    storm::expressions::Expression doubleConstExpression;
     
     ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
     ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
@@ -303,14 +257,11 @@ TEST(Expression, SubstitutionTest) {
     ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
     ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
     ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
-    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
-    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
-    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
     
     storm::expressions::Expression tempExpression;
-    ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolConstExpression);
+    ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolVarExpression);
 
-    std::map<std::string, storm::expressions::Expression> substution = { std::make_pair("y", doubleConstExpression), std::make_pair("x", storm::expressions::Expression::createTrue()), std::make_pair("a", storm::expressions::Expression::createTrue()) };
+    std::map<std::string, storm::expressions::Expression> substution = { std::make_pair("y", doubleVarExpression), std::make_pair("x", storm::expressions::Expression::createTrue()), std::make_pair("a", storm::expressions::Expression::createTrue()) };
     storm::expressions::Expression substitutedExpression;
     ASSERT_NO_THROW(substitutedExpression = tempExpression.substitute(substution));
     EXPECT_TRUE(substitutedExpression.simplify().isTrue());
@@ -347,9 +298,6 @@ TEST(Expression, SimpleEvaluationTest) {
     storm::expressions::Expression boolVarExpression;
     storm::expressions::Expression intVarExpression;
     storm::expressions::Expression doubleVarExpression;
-    storm::expressions::Expression boolConstExpression;
-    storm::expressions::Expression intConstExpression;
-    storm::expressions::Expression doubleConstExpression;
     
     ASSERT_NO_THROW(trueExpression = storm::expressions::Expression::createTrue());
     ASSERT_NO_THROW(falseExpression = storm::expressions::Expression::createFalse());
@@ -358,13 +306,10 @@ TEST(Expression, SimpleEvaluationTest) {
     ASSERT_NO_THROW(boolVarExpression = storm::expressions::Expression::createBooleanVariable("x"));
     ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
     ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
-    ASSERT_NO_THROW(boolConstExpression = storm::expressions::Expression::createBooleanConstant("a"));
-    ASSERT_NO_THROW(intConstExpression = storm::expressions::Expression::createIntegerConstant("b"));
-    ASSERT_NO_THROW(doubleConstExpression = storm::expressions::Expression::createDoubleConstant("c"));
     
     storm::expressions::Expression tempExpression;
     
-    ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolConstExpression);
+    ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolVarExpression);
     
     ASSERT_NO_THROW(storm::expressions::SimpleValuation valuation);
     storm::expressions::SimpleValuation valuation;
@@ -379,7 +324,7 @@ TEST(Expression, SimpleEvaluationTest) {
     ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
     EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
     ASSERT_NO_THROW(valuation.setBooleanValue("a", true));
-    EXPECT_TRUE(tempExpression.evaluateAsBool(&valuation));
+    EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
     ASSERT_NO_THROW(valuation.setIntegerValue("y", 3));
     EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
     

From a0df98a6ebcc509f7b46f4a9c0bc5f43b4119a88 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 14:35:40 +0200
Subject: [PATCH 106/147] Removed unnecessary virtual keyword in Expression
 class.

Former-commit-id: f879cd579ea0c3c8bda51626380411374e7b8db7
---
 src/storage/expressions/Expression.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index bfa2dc4d8..44f3e5728 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -178,28 +178,28 @@ namespace storm {
              *
              * @return The identifier associated with this expression.
              */
-            virtual std::string const& getIdentifier() const;
+            std::string const& getIdentifier() const;
             
             /*!
              * Retrieves whether the expression contains a variable.
              *
              * @return True iff the expression contains a variable.
              */
-            virtual bool containsVariables() const;
+            bool containsVariables() const;
             
             /*!
              * Retrieves whether the expression is a literal.
              *
              * @return True iff the expression is a literal.
              */
-            virtual bool isLiteral() const;
+            bool isLiteral() const;
             
             /*!
              * Retrieves whether the expression is a variable.
              *
              * @return True iff the expression is a variable.
              */
-            virtual bool isVariable() const;
+            bool isVariable() const;
             
             /*!
              * Checks if the expression is equal to the boolean literal true.

From 92ee6187fa41695068ad7746ca4ad7830c3b645e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 17:20:00 +0200
Subject: [PATCH 107/147] Added more query methods to expressions. SparseMatrix
 now keeps track of non zero entries and models show correct number of
 transitions by referring to nonzero entries rather than all entries in the
 matrix.

Former-commit-id: 48180be2fe33c7f12ad0ef20b1b7800910a73935
---
 src/models/AbstractModel.h                    |  2 +-
 src/storage/SparseMatrix.cpp                  | 29 ++++++++++++----
 src/storage/SparseMatrix.h                    | 10 ++++++
 src/storage/expressions/BaseExpression.cpp    |  8 +++++
 src/storage/expressions/BaseExpression.h      | 16 +++++++++
 .../BinaryBooleanFunctionExpression.cpp       | 10 ++++++
 .../BinaryBooleanFunctionExpression.h         |  1 +
 src/storage/expressions/BinaryExpression.cpp  |  6 +++-
 src/storage/expressions/BinaryExpression.h    |  1 +
 .../BinaryNumericalFunctionExpression.cpp     | 11 +++++++
 .../BinaryNumericalFunctionExpression.h       |  1 +
 .../expressions/BinaryRelationExpression.cpp  | 13 +++++++-
 .../expressions/BinaryRelationExpression.h    |  1 +
 src/storage/expressions/Expression.cpp        |  8 +++++
 src/storage/expressions/Expression.h          | 15 +++++++++
 .../expressions/IfThenElseExpression.cpp      | 30 +++++++++++++++++
 .../expressions/IfThenElseExpression.h        |  5 +++
 src/storage/expressions/OperatorType.h        | 33 +++++++++++++++++++
 .../UnaryBooleanFunctionExpression.cpp        |  6 ++++
 .../UnaryBooleanFunctionExpression.h          |  1 +
 src/storage/expressions/UnaryExpression.cpp   |  4 +++
 src/storage/expressions/UnaryExpression.h     |  1 +
 .../UnaryNumericalFunctionExpression.cpp      |  8 +++++
 .../UnaryNumericalFunctionExpression.h        |  1 +
 .../GmmxxDtmcPrctlModelCheckerTest.cpp        |  6 ++--
 test/functional/parser/AutoParserTest.cpp     | 12 +++----
 .../parser/DeterministicModelParserTest.cpp   |  4 +--
 .../GmmxxDtmcPrctModelCheckerTest.cpp         |  4 +--
 28 files changed, 224 insertions(+), 23 deletions(-)
 create mode 100644 src/storage/expressions/OperatorType.h

diff --git a/src/models/AbstractModel.h b/src/models/AbstractModel.h
index 301c806d3..05296c584 100644
--- a/src/models/AbstractModel.h
+++ b/src/models/AbstractModel.h
@@ -220,7 +220,7 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
 		 * @return The number of (non-zero) transitions of the model.
 		 */
 		virtual uint_fast64_t getNumberOfTransitions() const {
-			return this->getTransitionMatrix().getEntryCount();
+			return this->getTransitionMatrix().getNonzeroEntryCount();
 		}
 
         /*!
diff --git a/src/storage/SparseMatrix.cpp b/src/storage/SparseMatrix.cpp
index 6955ec053..e4d719006 100644
--- a/src/storage/SparseMatrix.cpp
+++ b/src/storage/SparseMatrix.cpp
@@ -218,17 +218,17 @@ namespace storm {
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix() : rowCount(0), columnCount(0), entryCount(0), columnsAndValues(), rowIndications(), rowGroupIndices() {
+        SparseMatrix<T>::SparseMatrix() : rowCount(0), columnCount(0), entryCount(0), nonzeroEntryCount(0), columnsAndValues(), rowIndications(), rowGroupIndices() {
             // Intentionally left empty.
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix(SparseMatrix<T> const& other) : rowCount(other.rowCount), columnCount(other.columnCount), entryCount(other.entryCount), columnsAndValues(other.columnsAndValues), rowIndications(other.rowIndications), rowGroupIndices(other.rowGroupIndices) {
+        SparseMatrix<T>::SparseMatrix(SparseMatrix<T> const& other) : rowCount(other.rowCount), columnCount(other.columnCount), entryCount(other.entryCount), nonzeroEntryCount(other.nonzeroEntryCount), columnsAndValues(other.columnsAndValues), rowIndications(other.rowIndications), rowGroupIndices(other.rowGroupIndices) {
             // Intentionally left empty.
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix(SparseMatrix<T>&& other) : rowCount(other.rowCount), columnCount(other.columnCount), entryCount(other.entryCount), columnsAndValues(std::move(other.columnsAndValues)), rowIndications(std::move(other.rowIndications)), rowGroupIndices(std::move(other.rowGroupIndices)) {
+        SparseMatrix<T>::SparseMatrix(SparseMatrix<T>&& other) : rowCount(other.rowCount), columnCount(other.columnCount), entryCount(other.entryCount), nonzeroEntryCount(other.nonzeroEntryCount), columnsAndValues(std::move(other.columnsAndValues)), rowIndications(std::move(other.rowIndications)), rowGroupIndices(std::move(other.rowGroupIndices)) {
             // Now update the source matrix
             other.rowCount = 0;
             other.columnCount = 0;
@@ -236,13 +236,21 @@ namespace storm {
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t> const& rowIndications, std::vector<std::pair<uint_fast64_t, T>> const& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), columnsAndValues(columnsAndValues), rowIndications(rowIndications), rowGroupIndices(rowGroupIndices) {
-            // Intentionally left empty.
+        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t> const& rowIndications, std::vector<std::pair<uint_fast64_t, T>> const& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), nonzeroEntryCount(0), columnsAndValues(columnsAndValues), rowIndications(rowIndications), rowGroupIndices(rowGroupIndices) {
+            for (auto const& element : *this) {
+                if (element.second != storm::utility::constantZero<T>()) {
+                    ++this->nonzeroEntryCount;
+                }
+            }
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t>&& rowIndications, std::vector<std::pair<uint_fast64_t, T>>&& columnsAndValues, std::vector<uint_fast64_t>&& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), columnsAndValues(std::move(columnsAndValues)), rowIndications(std::move(rowIndications)), rowGroupIndices(std::move(rowGroupIndices)) {
-            // Intentionally left empty.
+        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t>&& rowIndications, std::vector<std::pair<uint_fast64_t, T>>&& columnsAndValues, std::vector<uint_fast64_t>&& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), nonzeroEntryCount(0), columnsAndValues(std::move(columnsAndValues)), rowIndications(std::move(rowIndications)), rowGroupIndices(std::move(rowGroupIndices)) {
+            for (auto const& element : *this) {
+                if (element.second != storm::utility::constantZero<T>()) {
+                    ++this->nonzeroEntryCount;
+                }
+            }
         }
                 
         template<typename T>
@@ -252,6 +260,7 @@ namespace storm {
                 rowCount = other.rowCount;
                 columnCount = other.columnCount;
                 entryCount = other.entryCount;
+                nonzeroEntryCount = other.nonzeroEntryCount;
                 
                 columnsAndValues = other.columnsAndValues;
                 rowIndications = other.rowIndications;
@@ -268,6 +277,7 @@ namespace storm {
                 rowCount = other.rowCount;
                 columnCount = other.columnCount;
                 entryCount = other.entryCount;
+                nonzeroEntryCount = other.nonzeroEntryCount;
                 
                 columnsAndValues = std::move(other.columnsAndValues);
                 rowIndications = std::move(other.rowIndications);
@@ -330,6 +340,11 @@ namespace storm {
             return entryCount;
         }
         
+        template<typename T>
+        uint_fast64_t SparseMatrix<T>::getNonzeroEntryCount() const {
+            return nonzeroEntryCount;
+        }
+        
         template<typename T>
         uint_fast64_t SparseMatrix<T>::getRowGroupCount() const {
             return rowGroupIndices.size() - 1;
diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h
index f85dfdd52..b8b8b80d3 100644
--- a/src/storage/SparseMatrix.h
+++ b/src/storage/SparseMatrix.h
@@ -339,6 +339,13 @@ namespace storm {
              */
             uint_fast64_t getEntryCount() const;
             
+            /*!
+             * Returns the number of nonzero entries in the matrix.
+             *
+             * @return The number of nonzero entries in the matrix.
+             */
+            uint_fast64_t getNonzeroEntryCount() const;
+            
             /*!
              * Returns the number of row groups in the matrix.
              *
@@ -651,6 +658,9 @@ namespace storm {
             // The number of entries in the matrix.
             uint_fast64_t entryCount;
             
+            // The number of nonzero entries in the matrix.
+            uint_fast64_t nonzeroEntryCount;
+            
             // The storage for the columns and values of all entries in the matrix.
             std::vector<std::pair<uint_fast64_t, T>> columnsAndValues;
             
diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index 2aef5ab6e..c2f4a5ac3 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -49,6 +49,10 @@ namespace storm {
             LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to access identifier of non-constant, non-variable expression.");
         }
         
+        OperatorType BaseExpression::getOperator() const {
+            LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to access operator of non-function application expression.");
+        }
+        
         bool BaseExpression::containsVariables() const {
             return false;
         }
@@ -69,6 +73,10 @@ namespace storm {
             return false;
         }
         
+        bool BaseExpression::isFunctionApplication() const {
+            return false;
+        }
+        
         std::shared_ptr<BaseExpression const> BaseExpression::getSharedPointer() const {
             return this->shared_from_this();
         }
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 79dc09c1d..6a02b35ab 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -8,6 +8,7 @@
 
 #include "src/storage/expressions/Valuation.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
+#include "src/storage/expressions/OperatorType.h"
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/utility/OsDetection.h"
 
@@ -96,6 +97,14 @@ namespace storm {
              */
             virtual std::string const& getIdentifier() const;
             
+            /*!
+             * Retrieves the operator of a function application. This is only legal to call if the expression is
+             * function application.
+             *
+             * @return The operator associated with the function application.
+             */
+            virtual OperatorType getOperator() const;
+            
             /*!
              * Retrieves whether the expression contains a variable.
              *
@@ -131,6 +140,13 @@ namespace storm {
              */
             virtual bool isFalse() const;
             
+            /*!
+             * Checks if the expression is a function application (of any sort).
+             *
+             * @return True iff the expression is a function application.
+             */
+            virtual bool isFunctionApplication() const;
+            
             /*!
              * Retrieves the set of all variables that appear in the expression.
              *
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
index e270293a8..061c231af 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.cpp
@@ -13,6 +13,16 @@ namespace storm {
             return this->operatorType;
         }
         
+        storm::expressions::OperatorType BinaryBooleanFunctionExpression::getOperator() const {
+            switch (this->getOperatorType()) {
+                case OperatorType::And: return storm::expressions::OperatorType::And; break;
+                case OperatorType::Or: return storm::expressions::OperatorType::Or; break;
+                case OperatorType::Xor: return storm::expressions::OperatorType::Xor; break;
+                case OperatorType::Implies: return storm::expressions::OperatorType::Implies; break;
+                case OperatorType::Iff: return storm::expressions::OperatorType::Iff; break;
+            }
+        }
+                
         bool BinaryBooleanFunctionExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
             
diff --git a/src/storage/expressions/BinaryBooleanFunctionExpression.h b/src/storage/expressions/BinaryBooleanFunctionExpression.h
index 8b1bb7437..2a1d2417d 100644
--- a/src/storage/expressions/BinaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/BinaryBooleanFunctionExpression.h
@@ -33,6 +33,7 @@ namespace storm {
             virtual ~BinaryBooleanFunctionExpression() = default;
             
             // Override base class methods.
+            virtual storm::expressions::OperatorType getOperator() const override;
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
diff --git a/src/storage/expressions/BinaryExpression.cpp b/src/storage/expressions/BinaryExpression.cpp
index 0ca77aa0c..4d3c4be81 100644
--- a/src/storage/expressions/BinaryExpression.cpp
+++ b/src/storage/expressions/BinaryExpression.cpp
@@ -9,6 +9,10 @@ namespace storm {
             // Intentionally left empty.
         }
         
+        bool BinaryExpression::isFunctionApplication() const {
+            return true;
+        }
+        
         bool BinaryExpression::containsVariables() const {
             return this->getFirstOperand()->containsVariables() || this->getSecondOperand()->containsVariables();
         }
@@ -34,7 +38,7 @@ namespace storm {
         
         std::shared_ptr<BaseExpression const> BinaryExpression::getOperand(uint_fast64_t operandIndex) const {
             LOG_THROW(operandIndex < 2, storm::exceptions::InvalidAccessException, "Unable to access operand " << operandIndex << " in expression of arity 2.");
-            if (operandIndex == 1) {
+            if (operandIndex == 0) {
                 return this->getFirstOperand();
             } else {
                 return this->getSecondOperand();
diff --git a/src/storage/expressions/BinaryExpression.h b/src/storage/expressions/BinaryExpression.h
index dd81343ac..75c9283cb 100644
--- a/src/storage/expressions/BinaryExpression.h
+++ b/src/storage/expressions/BinaryExpression.h
@@ -30,6 +30,7 @@ namespace storm {
             virtual ~BinaryExpression() = default;
 
             // Override base class methods.
+            virtual bool isFunctionApplication() const override;
             virtual bool containsVariables() const override;
             virtual uint_fast64_t getArity() const override;
             virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
index 225bea963..f6172821d 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -14,6 +14,17 @@ namespace storm {
             return this->operatorType;
         }
         
+        storm::expressions::OperatorType BinaryNumericalFunctionExpression::getOperator() const {
+            switch (this->getOperatorType()) {
+                case OperatorType::Plus: return storm::expressions::OperatorType::Plus; break;
+                case OperatorType::Minus: return storm::expressions::OperatorType::Minus; break;
+                case OperatorType::Times: return storm::expressions::OperatorType::Times; break;
+                case OperatorType::Divide: return storm::expressions::OperatorType::Divide; break;
+                case OperatorType::Min: return storm::expressions::OperatorType::Min; break;
+                case OperatorType::Max: return storm::expressions::OperatorType::Max; break;
+            }
+        }
+        
         int_fast64_t BinaryNumericalFunctionExpression::evaluateAsInt(Valuation const* valuation) const {
             LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
             
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
index 4e8573a4c..13ee489df 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -33,6 +33,7 @@ namespace storm {
             virtual ~BinaryNumericalFunctionExpression() = default;
             
             // Override base class methods.
+            virtual storm::expressions::OperatorType getOperator() const override;
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
diff --git a/src/storage/expressions/BinaryRelationExpression.cpp b/src/storage/expressions/BinaryRelationExpression.cpp
index 7e48c2286..f31f97fce 100644
--- a/src/storage/expressions/BinaryRelationExpression.cpp
+++ b/src/storage/expressions/BinaryRelationExpression.cpp
@@ -8,7 +8,18 @@ namespace storm {
         BinaryRelationExpression::BinaryRelationExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, RelationType relationType) : BinaryExpression(returnType, firstOperand, secondOperand), relationType(relationType) {
             // Intentionally left empty.
         }
-                
+        
+        storm::expressions::OperatorType BinaryRelationExpression::getOperator() const {
+            switch (this->getRelationType()) {
+                case RelationType::Equal: return storm::expressions::OperatorType::Equal; break;
+                case RelationType::NotEqual: return storm::expressions::OperatorType::NotEqual; break;
+                case RelationType::Less: return storm::expressions::OperatorType::Less; break;
+                case RelationType::LessOrEqual: return storm::expressions::OperatorType::LessOrEqual; break;
+                case RelationType::Greater: return storm::expressions::OperatorType::Greater; break;
+                case RelationType::GreaterOrEqual: return storm::expressions::OperatorType::GreaterOrEqual; break;
+            }
+        }
+        
         bool BinaryRelationExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
 
diff --git a/src/storage/expressions/BinaryRelationExpression.h b/src/storage/expressions/BinaryRelationExpression.h
index b88ef71f9..4e03a598e 100644
--- a/src/storage/expressions/BinaryRelationExpression.h
+++ b/src/storage/expressions/BinaryRelationExpression.h
@@ -33,6 +33,7 @@ namespace storm {
             virtual ~BinaryRelationExpression() = default;
             
             // Override base class methods.
+            virtual storm::expressions::OperatorType getOperator() const override;
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 863d630f3..e30b53927 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -55,6 +55,14 @@ namespace storm {
             return Expression(this->getBaseExpression().simplify());
         }
         
+        OperatorType Expression::getOperator() const {
+            return this->getBaseExpression().getOperator();
+        }
+        
+        bool Expression::isFunctionApplication() const {
+            return this->getBaseExpression().isFunctionApplication();
+        }
+        
         uint_fast64_t Expression::getArity() const {
             return this->getBaseExpression().getArity();
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 44f3e5728..0c55408dc 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -157,6 +157,21 @@ namespace storm {
              */
             Expression simplify();
             
+            /*!
+             * Retrieves the operator of a function application. This is only legal to call if the expression is
+             * function application.
+             *
+             * @return The operator associated with the function application.
+             */
+            OperatorType getOperator() const;
+            
+            /*!
+             * Checks if the expression is a function application (of any sort).
+             *
+             * @return True iff the expression is a function application.
+             */
+            bool isFunctionApplication() const;
+            
             /*!
              * Retrieves the arity of the expression.
              *
diff --git a/src/storage/expressions/IfThenElseExpression.cpp b/src/storage/expressions/IfThenElseExpression.cpp
index 4cc028b3c..bbd0b28d2 100644
--- a/src/storage/expressions/IfThenElseExpression.cpp
+++ b/src/storage/expressions/IfThenElseExpression.cpp
@@ -1,11 +1,41 @@
 #include "src/storage/expressions/IfThenElseExpression.h"
 
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidAccessException.h"
+
 namespace storm {
     namespace expressions {
         IfThenElseExpression::IfThenElseExpression(ExpressionReturnType returnType, std::shared_ptr<BaseExpression const> const& condition, std::shared_ptr<BaseExpression const> const& thenExpression, std::shared_ptr<BaseExpression const> const& elseExpression) : BaseExpression(returnType), condition(condition), thenExpression(thenExpression), elseExpression(elseExpression) {
             // Intentionally left empty.
         }
         
+        std::shared_ptr<BaseExpression const> IfThenElseExpression::getOperand(uint_fast64_t operandIndex) const {
+            LOG_THROW(operandIndex < 3, storm::exceptions::InvalidAccessException, "Unable to access operand " << operandIndex << " in expression of arity 3.");
+            if (operandIndex == 0) {
+                return this->getCondition();
+            } else if (operandIndex == 1) {
+                return this->getThenExpression();
+            } else {
+                return this->getElseExpression();
+            }
+        }
+        
+        OperatorType IfThenElseExpression::getOperator() const {
+            return OperatorType::Ite;
+        }
+        
+        bool IfThenElseExpression::isFunctionApplication() const {
+            return true;
+        }
+        
+        bool IfThenElseExpression::containsVariables() const {
+            return this->getCondition()->containsVariables() || this->getThenExpression()->containsVariables() || this->getElseExpression()->containsVariables();
+        }
+        
+        uint_fast64_t IfThenElseExpression::getArity() const {
+            return 3;
+        }
+        
         bool IfThenElseExpression::evaluateAsBool(Valuation const* valuation) const {
             bool conditionValue = this->condition->evaluateAsBool(valuation);
             if (conditionValue) {
diff --git a/src/storage/expressions/IfThenElseExpression.h b/src/storage/expressions/IfThenElseExpression.h
index b44de20be..425633850 100644
--- a/src/storage/expressions/IfThenElseExpression.h
+++ b/src/storage/expressions/IfThenElseExpression.h
@@ -27,6 +27,11 @@ namespace storm {
             virtual ~IfThenElseExpression() = default;
             
             // Override base class methods.
+            virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
+            virtual OperatorType getOperator() const override;
+            virtual bool isFunctionApplication() const override;
+            virtual bool containsVariables() const override;
+            virtual uint_fast64_t getArity() const override;
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
diff --git a/src/storage/expressions/OperatorType.h b/src/storage/expressions/OperatorType.h
new file mode 100644
index 000000000..8a4f199aa
--- /dev/null
+++ b/src/storage/expressions/OperatorType.h
@@ -0,0 +1,33 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_OPERATORTYPE_H_
+#define STORM_STORAGE_EXPRESSIONS_OPERATORTYPE_H_
+
+namespace storm {
+    namespace expressions {
+        // An enum representing all possible operator types.
+        enum class OperatorType {
+            And,
+            Or,
+            Xor,
+            Implies,
+            Iff,
+            Plus,
+            Minus,
+            Times,
+            Divide,
+            Min,
+            Max,
+            Equal,
+            NotEqual,
+            Less,
+            LessOrEqual,
+            Greater,
+            GreaterOrEqual,
+            Not,
+            Floor,
+            Ceil,
+            Ite
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_OPERATORTYPE_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
index 7e405bb29..1d9e59119 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.cpp
@@ -13,6 +13,12 @@ namespace storm {
             return this->operatorType;
         }
         
+        storm::expressions::OperatorType UnaryBooleanFunctionExpression::getOperator() const {
+            switch (this->getOperatorType()) {
+                case OperatorType::Not: return storm::expressions::OperatorType::Not;
+            }
+        }
+        
         bool UnaryBooleanFunctionExpression::evaluateAsBool(Valuation const* valuation) const {
             LOG_THROW(this->hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
 
diff --git a/src/storage/expressions/UnaryBooleanFunctionExpression.h b/src/storage/expressions/UnaryBooleanFunctionExpression.h
index 1f2800d8e..c69c6f886 100644
--- a/src/storage/expressions/UnaryBooleanFunctionExpression.h
+++ b/src/storage/expressions/UnaryBooleanFunctionExpression.h
@@ -32,6 +32,7 @@ namespace storm {
             virtual ~UnaryBooleanFunctionExpression() = default;
             
             // Override base class methods.
+            virtual storm::expressions::OperatorType getOperator() const override;
             virtual bool evaluateAsBool(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
             virtual void accept(ExpressionVisitor* visitor) const override;
diff --git a/src/storage/expressions/UnaryExpression.cpp b/src/storage/expressions/UnaryExpression.cpp
index 62ff442ed..5d8262766 100644
--- a/src/storage/expressions/UnaryExpression.cpp
+++ b/src/storage/expressions/UnaryExpression.cpp
@@ -9,6 +9,10 @@ namespace storm {
             // Intentionally left empty.
         }
 
+        bool UnaryExpression::isFunctionApplication() const {
+            return true;
+        }
+        
         bool UnaryExpression::containsVariables() const {
             return this->getOperand()->containsVariables();
         }
diff --git a/src/storage/expressions/UnaryExpression.h b/src/storage/expressions/UnaryExpression.h
index 8ad304ce1..a387ad8d5 100644
--- a/src/storage/expressions/UnaryExpression.h
+++ b/src/storage/expressions/UnaryExpression.h
@@ -26,6 +26,7 @@ namespace storm {
             virtual ~UnaryExpression() = default;
             
             // Override base class methods.
+            virtual bool isFunctionApplication() const override;
             virtual bool containsVariables() const override;
             virtual uint_fast64_t getArity() const override;
             virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override;
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
index 02a4bee30..972f2a24a 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
@@ -14,6 +14,14 @@ namespace storm {
             return this->operatorType;
         }
         
+        storm::expressions::OperatorType UnaryNumericalFunctionExpression::getOperator() const {
+            switch (this->getOperatorType()) {
+                case OperatorType::Minus: return storm::expressions::OperatorType::Minus; break;
+                case OperatorType::Floor: return storm::expressions::OperatorType::Floor; break;
+                case OperatorType::Ceil: return storm::expressions::OperatorType::Ceil; break;
+            }
+        }
+        
         int_fast64_t UnaryNumericalFunctionExpression::evaluateAsInt(Valuation const* valuation) const {
             LOG_THROW(this->hasIntegralReturnType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
 
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storage/expressions/UnaryNumericalFunctionExpression.h
index daa0df40f..10b85e63e 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.h
@@ -32,6 +32,7 @@ namespace storm {
             virtual ~UnaryNumericalFunctionExpression() = default;
             
             // Override base class methods.
+            virtual storm::expressions::OperatorType getOperator() const override;
             virtual int_fast64_t evaluateAsInt(Valuation const* valuation = nullptr) const override;
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
             virtual std::shared_ptr<BaseExpression const> simplify() const override;
diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
index fdff14a66..dc2d6d703 100644
--- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
+++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
@@ -18,7 +18,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) {
 	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 13ull);
-	ASSERT_EQ(dtmc->getNumberOfTransitions(), 27ull);
+	ASSERT_EQ(dtmc->getNumberOfTransitions(), 20ull);
 
 	storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>());
 
@@ -74,7 +74,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) {
 	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 8607ull);
-	ASSERT_EQ(dtmc->getNumberOfTransitions(), 22460ull);
+	ASSERT_EQ(dtmc->getNumberOfTransitions(), 15113ull);
 
 	storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>());
 
@@ -119,7 +119,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
 	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 12400ull);
-	ASSERT_EQ(dtmc->getNumberOfTransitions(), 28894ull);
+	ASSERT_EQ(dtmc->getNumberOfTransitions(), 16495ull);
 
 	storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>());
 
diff --git a/test/functional/parser/AutoParserTest.cpp b/test/functional/parser/AutoParserTest.cpp
index 3c4927ecd..7c3fcb483 100644
--- a/test/functional/parser/AutoParserTest.cpp
+++ b/test/functional/parser/AutoParserTest.cpp
@@ -24,7 +24,7 @@ TEST(AutoParserTest, BasicParsing) {
 	// Test if parsed correctly.
 	ASSERT_EQ(storm::models::DTMC, modelPtr->getType());
 	ASSERT_EQ(12, modelPtr->getNumberOfStates());
-	ASSERT_EQ(32, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(26, modelPtr->getNumberOfTransitions());
 	ASSERT_EQ(1, modelPtr->getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(modelPtr->hasAtomicProposition("three"));
 	ASSERT_FALSE(modelPtr->hasStateRewards());
@@ -56,21 +56,21 @@ TEST(AutoParserTest, Decision) {
 	std::shared_ptr<storm::models::AbstractModel<double>> modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/dtmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 	ASSERT_EQ(storm::models::DTMC, modelPtr->getType());
 	ASSERT_EQ(12, modelPtr->getNumberOfStates());
-	ASSERT_EQ(32, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(26, modelPtr->getNumberOfTransitions());
 
 	// Ctmc
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ctmc.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 	ASSERT_EQ(storm::models::CTMC, modelPtr->getType());
 	ASSERT_EQ(12, modelPtr->getNumberOfStates());
-	ASSERT_EQ(31, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(26, modelPtr->getNumberOfTransitions());
 
 	// Mdp
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/mdp.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 	ASSERT_EQ(storm::models::MDP, modelPtr->getType());
 	ASSERT_EQ(12, modelPtr->getNumberOfStates());
-	ASSERT_EQ(36, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(28, modelPtr->getNumberOfTransitions());
 
 	// Ctmdp
 	// Note: For now we use the Mdp from above just given the ctmdp hint, since the implementation of the Ctmdp model seems not Quite right yet.
@@ -80,12 +80,12 @@ TEST(AutoParserTest, Decision) {
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ctmdp.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 	ASSERT_EQ(storm::models::CTMDP, modelPtr->getType());
 	ASSERT_EQ(12, modelPtr->getNumberOfStates());
-	ASSERT_EQ(36, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(28, modelPtr->getNumberOfTransitions());
 
 	// MA
 	modelPtr.reset();
 	modelPtr = storm::parser::AutoParser::parseModel(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/autoParser/ma.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/autoParser.lab");
 	ASSERT_EQ(storm::models::MA, modelPtr->getType());
 	ASSERT_EQ(12, modelPtr->getNumberOfStates());
-	ASSERT_EQ(35, modelPtr->getNumberOfTransitions());
+	ASSERT_EQ(27, modelPtr->getNumberOfTransitions());
 }
diff --git a/test/functional/parser/DeterministicModelParserTest.cpp b/test/functional/parser/DeterministicModelParserTest.cpp
index 4a62e5e6e..1b6fe71db 100644
--- a/test/functional/parser/DeterministicModelParserTest.cpp
+++ b/test/functional/parser/DeterministicModelParserTest.cpp
@@ -26,7 +26,7 @@ TEST(DeterministicModelParserTest, BasicDtmcParsing) {
 	storm::models::Dtmc<double> dtmc(storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"));
 
 	ASSERT_EQ(8, dtmc.getNumberOfStates());
-	ASSERT_EQ(21, dtmc.getNumberOfTransitions());
+	ASSERT_EQ(16, dtmc.getNumberOfTransitions());
 
 	ASSERT_EQ(2, dtmc.getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(dtmc.getInitialStates().get(0));
@@ -58,7 +58,7 @@ TEST(DeterministicModelParserTest, BasicCtmcParsing) {
 	storm::models::Ctmc<double> ctmc(storm::parser::DeterministicModelParser::parseCtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_general.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.state.rew", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew"));
 
 	ASSERT_EQ(8, ctmc.getNumberOfStates());
-	ASSERT_EQ(21, ctmc.getNumberOfTransitions());
+	ASSERT_EQ(16, ctmc.getNumberOfTransitions());
 
 	ASSERT_EQ(2, ctmc.getInitialStates().getNumberOfSetBits());
 	ASSERT_TRUE(ctmc.getInitialStates().get(0));
diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
index 809f602fb..2fddf8702 100644
--- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
+++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
@@ -17,7 +17,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) {
 	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 2036647ull);
-	ASSERT_EQ(dtmc->getNumberOfTransitions(), 8973900ull);
+	ASSERT_EQ(dtmc->getNumberOfTransitions(), 7362293ull);
 
 	storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>());
 
@@ -71,7 +71,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
 	std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>();
 
 	ASSERT_EQ(dtmc->getNumberOfStates(), 1312334ull);
-	ASSERT_EQ(dtmc->getNumberOfTransitions(), 2886810ull);
+	ASSERT_EQ(dtmc->getNumberOfTransitions(), 1574477ull);
 
 	storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>());
 

From 2d8cc2efcd8d8f1cb269cb3f29207e3fbdaec7d0 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 18:14:45 +0200
Subject: [PATCH 108/147] Added reordering functionality to DD interface.

Former-commit-id: ffb8ad62f132a26a650a988ba117f27c967fb524
---
 src/storage/dd/CuddDdManager.cpp | 21 +++++++++++++++++++++
 src/storage/dd/CuddDdManager.h   | 26 ++++++++++++++++++++++++++
 src/storage/prism/Program.cpp    |  2 +-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 64261d0aa..b3854ee36 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -224,6 +224,10 @@ namespace storm {
         Cudd& DdManager<DdType::CUDD>::getCuddManager() {
             return this->cuddManager;
         }
+
+        Cudd const& DdManager<DdType::CUDD>::getCuddManager() const {
+            return this->cuddManager;
+        }
         
         std::vector<std::string> DdManager<DdType::CUDD>::getDdVariableNames() const {
             // First, we initialize a list DD variables and their names.
@@ -246,5 +250,22 @@ namespace storm {
             
             return result;
         }
+        
+        void DdManager<DdType::CUDD>::allowDynamicReordering(bool value) {
+            if (value) {
+                this->getCuddManager().AutodynEnable(CUDD_REORDER_GROUP_SIFT_CONV);
+            } else {
+                this->getCuddManager().AutodynDisable();
+            }
+        }
+        
+        bool DdManager<DdType::CUDD>::isDynamicReorderingAllowed() const {
+            Cudd_ReorderingType type;
+            return this->getCuddManager().ReorderingStatus(&type);
+        }
+        
+        void DdManager<DdType::CUDD>::triggerReordering() {
+            this->getCuddManager().ReduceHeap(CUDD_REORDER_GROUP_SIFT_CONV, 0);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 25844598c..6fba4d254 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -138,6 +138,25 @@ namespace storm {
              */
             bool hasMetaVariable(std::string const& metaVariableName) const;
             
+            /*!
+             * Sets whether or not dynamic reordering is allowed for the DDs managed by this manager.
+             *
+             * @param value If set to true, dynamic reordering is allowed and forbidden otherwise.
+             */
+            void allowDynamicReordering(bool value);
+            
+            /*!
+             * Retrieves whether dynamic reordering is currently allowed.
+             *
+             * @return True iff dynamic reordering is currently allowed.
+             */
+            bool isDynamicReorderingAllowed() const;
+            
+            /*!
+             * Triggers a reordering of the DDs managed by this manager.
+             */
+            void triggerReordering();
+            
         private:
             /*!
              * Retrieves a list of names of the DD variables in the order of their index.
@@ -153,6 +172,13 @@ namespace storm {
              */
             Cudd& getCuddManager();
             
+            /*!
+             * Retrieves the underlying CUDD manager.
+             *
+             * @return The underlying CUDD manager.
+             */
+            Cudd const& getCuddManager() const;
+            
             // A mapping from variable names to the meta variable information.
             std::unordered_map<std::string, DdMetaVariable<DdType::CUDD>> metaVariableMap;
             
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 10a1114e6..617a1c52b 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -13,7 +13,7 @@ namespace storm {
         Program::Program(ModelType modelType, std::vector<Constant> const& constants, std::vector<BooleanVariable> const& globalBooleanVariables, std::vector<IntegerVariable> const& globalIntegerVariables, std::vector<Formula> const& formulas, std::vector<Module> const& modules, std::vector<RewardModel> const& rewardModels, bool fixInitialConstruct, storm::prism::InitialConstruct const& initialConstruct, std::vector<Label> const& labels, std::string const& filename, uint_fast64_t lineNumber, bool checkValidity) : LocatedInformation(filename, lineNumber), modelType(modelType), constants(constants), constantToIndexMap(), globalBooleanVariables(globalBooleanVariables), globalBooleanVariableToIndexMap(), globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(), formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(), rewardModels(rewardModels), rewardModelToIndexMap(), initialConstruct(initialConstruct), labels(labels), labelToIndexMap(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
             this->createMappings();
             
-            // Create a new initial construct if none was given explicitly.
+            // Create a new initial construct if the corresponding flag was set.
             if (fixInitialConstruct) {
                 if (this->getInitialConstruct().getInitialStatesExpression().isFalse()) {
                     storm::expressions::Expression newInitialExpression = storm::expressions::Expression::createTrue();

From db232fe39bf256865e69f19cec2e2b9abbcb98c4 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 19:33:54 +0200
Subject: [PATCH 109/147] Moved from pair to MatrixEntry as the basic building
 block of the matrix. Now matrix elements can be accessed in a more readable
 way.

Former-commit-id: f6514eb0cd627fba813d78d4626763afda0734ee
---
 src/adapters/GmmxxAdapter.h                   |   4 +-
 .../MILPMinimalLabelSetGenerator.h            |  50 ++---
 .../PathBasedSubsystemGenerator.h             | 144 +++++++-------
 .../SparseMarkovAutomatonCslModelChecker.h    |  32 +--
 src/models/AbstractDeterministicModel.h       |   6 +-
 src/models/AbstractNondeterministicModel.h    |   4 +-
 src/models/Dtmc.h                             |  12 +-
 src/models/MarkovAutomaton.h                  |  12 +-
 .../MaximalEndComponentDecomposition.cpp      |   8 +-
 src/storage/SparseMatrix.cpp                  | 137 ++++++++-----
 src/storage/SparseMatrix.h                    |  90 ++++++++-
 ...tronglyConnectedComponentDecomposition.cpp |  20 +-
 src/utility/counterexamples.h                 |  28 +--
 src/utility/graph.h                           |  60 +++---
 src/utility/matrix.h                          |   2 +-
 ...eterministicSparseTransitionParserTest.cpp | 168 ++++++++--------
 ...kovAutomatonSparseTransitionParserTest.cpp |  48 ++---
 ...eterministicSparseTransitionParserTest.cpp | 184 +++++++++---------
 test/functional/storage/SparseMatrixTest.cpp  |  26 +--
 test/performance/storage/SparseMatrixTest.cpp |   2 +-
 20 files changed, 576 insertions(+), 461 deletions(-)

diff --git a/src/adapters/GmmxxAdapter.h b/src/adapters/GmmxxAdapter.h
index ff35800b2..b1d2206a5 100644
--- a/src/adapters/GmmxxAdapter.h
+++ b/src/adapters/GmmxxAdapter.h
@@ -51,8 +51,8 @@ public:
         columns.reserve(matrix.getEntryCount());
         
         for (auto const& entry : matrix) {
-            columns.emplace_back(entry.first);
-            values.emplace_back(entry.second);
+            columns.emplace_back(entry.getColumn());
+            values.emplace_back(entry.getValue());
         }
         
         std::swap(result->ir, columns);
diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index 197db76ab..4e0f9381c 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -130,7 +130,7 @@ namespace storm {
                         bool allSuccessorsProblematic = true;
                         for (auto const& successorEntry : transitionMatrix.getRow(row)) {
                             // If there is a relevant successor, we need to add the labels of the current choice.
-                            if (stateInformation.relevantStates.get(successorEntry.first) || psiStates.get(successorEntry.first)) {
+                            if (stateInformation.relevantStates.get(successorEntry.getColumn()) || psiStates.get(successorEntry.getColumn())) {
                                 for (auto const& label : choiceLabeling[row]) {
                                     result.allRelevantLabels.insert(label);
                                 }
@@ -139,7 +139,7 @@ namespace storm {
                                     result.relevantChoicesForRelevantStates[state].push_back(row);
                                 }
                             }
-                            if (!stateInformation.problematicStates.get(successorEntry.first)) {
+                            if (!stateInformation.problematicStates.get(successorEntry.getColumn())) {
                                 allSuccessorsProblematic = false;
                             }
                         }
@@ -297,11 +297,11 @@ namespace storm {
                     std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
                     for (uint_fast64_t row : relevantChoicesForState) {
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(row)) {
-                            if (stateInformation.relevantStates.get(successorEntry.first)) {
-                                if (resultingMap.find(successorEntry.first) == resultingMap.end()) {
+                            if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
+                                if (resultingMap.find(successorEntry.getColumn()) == resultingMap.end()) {
                                     variableNameBuffer.str("");
                                     variableNameBuffer.clear();
-                                    variableNameBuffer << "r" << successorEntry.first;
+                                    variableNameBuffer << "r" << successorEntry.getColumn();
                                     resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
                                     ++numberOfVariablesCreated;
                                 }
@@ -330,11 +330,11 @@ namespace storm {
                     std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
                     for (uint_fast64_t row : relevantChoicesForState) {
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(row)) {
-                            if (stateInformation.relevantStates.get(successorEntry.first)) {
+                            if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
                                 variableNameBuffer.str("");
                                 variableNameBuffer.clear();
-                                variableNameBuffer << "t" << state << "to" << successorEntry.first;
-                                resultingMap[std::make_pair(state, successorEntry.first)] = solver.createBinaryVariable(variableNameBuffer.str(), 0);
+                                variableNameBuffer << "t" << state << "to" << successorEntry.getColumn();
+                                resultingMap[std::make_pair(state, successorEntry.getColumn())] = solver.createBinaryVariable(variableNameBuffer.str(), 0);
                                 ++numberOfVariablesCreated;
                             }
                         }
@@ -544,11 +544,11 @@ namespace storm {
                         
                         double rightHandSide = 1;
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
-                            if (stateInformation.relevantStates.get(successorEntry.first)) {
-                                variables.push_back(static_cast<int>(variableInformation.stateToProbabilityVariableIndexMap.at(successorEntry.first)));
-                                coefficients.push_back(-successorEntry.second);
-                            } else if (psiStates.get(successorEntry.first)) {
-                                rightHandSide += successorEntry.second;
+                            if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
+                                variables.push_back(static_cast<int>(variableInformation.stateToProbabilityVariableIndexMap.at(successorEntry.getColumn())));
+                                coefficients.push_back(-successorEntry.getValue());
+                            } else if (psiStates.get(successorEntry.getColumn())) {
+                                rightHandSide += successorEntry.getValue();
                             }
                         }
                         
@@ -602,7 +602,7 @@ namespace storm {
                         coefficients.push_back(1);
                         
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
-                            variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(stateListPair.first, successorEntry.first)));
+                            variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(stateListPair.first, successorEntry.getColumn())));
                             coefficients.push_back(-1);
                         }
                         
@@ -619,9 +619,9 @@ namespace storm {
                             
                             variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(state));
                             coefficients.push_back(1);
-                            variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(successorEntry.first));
+                            variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(successorEntry.getColumn()));
                             coefficients.push_back(-1);
-                            variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(state, successorEntry.first)));
+                            variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(state, successorEntry.getColumn())));
                             coefficients.push_back(1);
                             
                             solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS, 1);
@@ -677,7 +677,7 @@ namespace storm {
                     for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
                         bool psiStateReachableInOneStep = false;
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
-                            if (psiStates.get(successorEntry.first)) {
+                            if (psiStates.get(successorEntry.getColumn())) {
                                 psiStateReachableInOneStep = true;
                             }
                         }
@@ -690,8 +690,8 @@ namespace storm {
                             coefficients.push_back(1);
                             
                             for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
-                                if (state != successorEntry.first && stateInformation.relevantStates.get(successorEntry.first)) {
-                                    std::list<uint_fast64_t> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(successorEntry.first);
+                                if (state != successorEntry.getColumn() && stateInformation.relevantStates.get(successorEntry.getColumn())) {
+                                    std::list<uint_fast64_t> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(successorEntry.getColumn());
                                     
                                     for (auto choiceVariableIndex : successorChoiceVariableIndices) {
                                         variables.push_back(choiceVariableIndex);
@@ -720,8 +720,8 @@ namespace storm {
                     // Compute the set of predecessors.
                     std::unordered_set<uint_fast64_t> predecessors;
                     for (auto const& predecessorEntry : backwardTransitions.getRow(state)) {
-                        if (state != predecessorEntry.first) {
-                            predecessors.insert(predecessorEntry.first);
+                        if (state != predecessorEntry.getColumn()) {
+                            predecessors.insert(predecessorEntry.getColumn());
                         }
                     }
                     
@@ -737,7 +737,7 @@ namespace storm {
                             
                             // Check if the current choice targets the current state.
                             for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(relevantChoice)) {
-                                if (state == successorEntry.first) {
+                                if (state == successorEntry.getColumn()) {
                                     choiceTargetsCurrentState = true;
                                     break;
                                 }
@@ -782,8 +782,8 @@ namespace storm {
                 for (auto psiState : psiStates) {
                     // Compute the set of predecessors.
                     for (auto const& predecessorEntry : backwardTransitions.getRow(psiState)) {
-                        if (psiState != predecessorEntry.first) {
-                            predecessors.insert(predecessorEntry.first);
+                        if (psiState != predecessorEntry.getColumn()) {
+                            predecessors.insert(predecessorEntry.getColumn());
                         }
                     }
                 }
@@ -800,7 +800,7 @@ namespace storm {
                         
                         // Check if the current choice targets the current state.
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(relevantChoice)) {
-                            if (psiStates.get(successorEntry.first)) {
+                            if (psiStates.get(successorEntry.getColumn())) {
                                 choiceTargetsPsiState = true;
                                 break;
                             }
diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h
index 11e24d00d..2325eebe8 100644
--- a/src/counterexamples/PathBasedSubsystemGenerator.h
+++ b/src/counterexamples/PathBasedSubsystemGenerator.h
@@ -69,31 +69,31 @@ public:
 
 				for(auto const& trans : transMat.getRow(init)) {
 					//save transition only if it's no 'virtual transition of prob 0 and it doesn't go from init state to init state.
-					if(trans.second != (T) 0 && !subSysStates.get(trans.first)) {
+					if(trans.getValue() != (T) 0 && !subSysStates.get(trans.getColumn())) {
 						//new state?
-						if(distances[trans.first].second == (T) -1) {
-							distances[trans.first].first = init;
-							distances[trans.first].second = trans.second;
+						if(distances[trans.getColumn()].second == (T) -1) {
+							distances[trans.getColumn()].first = init;
+							distances[trans.getColumn()].second = trans.getValue();
 
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
 						}
-						else if(distances[trans.first].second < trans.second){
+						else if(distances[trans.getColumn()].second < trans.getValue()){
 							//This state has already been discovered
 							//And the distance can be improved by using this transition.
 
 							//find state in set, remove it, reenter it with new and correct values.
-							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
+							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
 							for(;range.first != range.second; range.first++) {
-								if(trans.first == range.first->first) {
+								if(trans.getColumn() == range.first->first) {
 									activeSet.erase(range.first);
 									break;
 								}
 							}
 
-							distances[trans.first].first = init;
-							distances[trans.first].second = trans.second;
+							distances[trans.getColumn()].first = init;
+							distances[trans.getColumn()].second = trans.getValue();
 
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, trans.second));
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), trans.getValue()));
 						}
 					}
 				}
@@ -115,36 +115,36 @@ public:
 				// Look at all neighbors
 				for(auto const& trans : transMat.getRow(activeState.first)) {
 					// Only consider the transition if it's not virtual
-					if(trans.second != (T) 0) {
+					if(trans.getValue() != (T) 0) {
 
-						T distance = activeState.second * trans.second;
+						T distance = activeState.second * trans.getValue();
 
 						//not discovered or initial terminal state
-						if(distances[trans.first].second == (T)-1) {
+						if(distances[trans.getColumn()].second == (T)-1) {
 							//New state discovered -> save it
-							distances[trans.first].first = activeState.first;
-							distances[trans.first].second = distance;
+							distances[trans.getColumn()].first = activeState.first;
+							distances[trans.getColumn()].second = distance;
 
 							// push newly discovered state into activeSet
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
 						}
-						else if(distances[trans.first].second < distance ){
+						else if(distances[trans.getColumn()].second < distance) {
 							//This state has already been discovered
 							//And the distance can be improved by using this transition.
 
 							//find state in set, remove it, reenter it with new and correct values.
 
-							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
+							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
 							for(;range.first != range.second; range.first++) {
-								if(trans.first == range.first->first) {
+								if(trans.getColumn() == range.first->first) {
 									activeSet.erase(range.first);
 									break;
 								}
 							}
 
-							distances[trans.first].first = activeState.first;
-							distances[trans.first].second = distance;
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
+							distances[trans.getColumn()].first = activeState.first;
+							distances[trans.getColumn()].second = distance;
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
 						}
 					}
 				}
@@ -182,33 +182,33 @@ public:
 
 				for(auto const& trans : transMat.getRow(init)) {
 					//save transition only if it's no 'virtual transition of prob 0 and it doesn't go from init state to init state.
-					if(trans.second != (T) 0 && !subSysStates.get(trans.first)) {
+					if(trans.getValue() != (T) 0 && !subSysStates.get(trans.getColumn())) {
 						//new state?
-						if(distances[trans.first].second == (T) -1) {
+						if(distances[trans.getColumn()].second == (T) -1) {
 							//for initialization of subsys -> subsys search use prob (init -> subsys state -> found state) instead of prob(subsys state -> found state)
-							distances[trans.first].first = init;
-							distances[trans.first].second = trans.second * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
+							distances[trans.getColumn()].first = init;
+							distances[trans.getColumn()].second = trans.getValue() * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
 
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
 						}
-						else if(distances[trans.first].second < trans.second * itDistances[init].second){
+						else if(distances[trans.getColumn()].second < trans.getValue() * itDistances[init].second){
 							//This state has already been discovered
 							//And the distance can be improved by using this transition.
 
 							//find state in set, remove it, reenter it with new and correct values.
-							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
+							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
 							for(;range.first != range.second; range.first++) {
-								if(trans.first == range.first->first) {
+								if(trans.getColumn() == range.first->first) {
 									activeSet.erase(range.first);
 									break;
 								}
 							}
 
 							//for initialization of subsys -> subsys search use prob (init -> subsys state -> found state) instead of prob(subsys state -> found state)
-							distances[trans.first].first = init;
-							distances[trans.first].second = trans.second * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
+							distances[trans.getColumn()].first = init;
+							distances[trans.getColumn()].second = trans.getValue() * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
 
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, trans.second));
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), trans.getValue()));
 						}
 					}
 				}
@@ -225,7 +225,7 @@ public:
 			activeSet.erase(--activeSet.end());
 
 			// Always stop at first target/terminal state
-			//if(terminalStates.get(activeState.first) || subSysStates.get(activeState.first)) break;
+			//if(terminalStates.get(activeState.getColumn()) || subSysStates.get(activeState.getColumn())) break;
 
 			// If this is an initial state, do not consider its outgoing transitions, since all relevant ones have already been considered
 			// Same goes for forbidden states since they may not be used on a path, except as last node.
@@ -233,36 +233,36 @@ public:
 				// Look at all neighbors
 				for(auto const& trans : transMat.getRow(activeState.first)) {
 					// Only consider the transition if it's not virtual
-					if(trans.second != (T) 0) {
+					if(trans.getValue() != (T) 0) {
 
-						T distance = activeState.second * trans.second;
+						T distance = activeState.second * trans.getValue();
 
 						//not discovered or initial terminal state
-						if(distances[trans.first].second == (T)-1) {
+						if(distances[trans.getColumn()].second == (T)-1) {
 							//New state discovered -> save it
-							distances[trans.first].first = activeState.first;
-							distances[trans.first].second = distance;
+							distances[trans.getColumn()].first = activeState.first;
+							distances[trans.getColumn()].second = distance;
 
 							// push newly discovered state into activeSet
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
 						}
-						else if(distances[trans.first].second < distance ){
+						else if(distances[trans.getColumn()].second < distance) {
 							//This state has already been discovered
 							//And the distance can be improved by using this transition.
 
 							//find state in set, remove it, reenter it with new and correct values.
 
-							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
+							auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
 							for(;range.first != range.second; range.first++) {
-								if(trans.first == range.first->first) {
+								if(trans.getColumn() == range.first->first) {
 									activeSet.erase(range.first);
 									break;
 								}
 							}
 
-							distances[trans.first].first = activeState.first;
-							distances[trans.first].second = distance;
-							activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
+							distances[trans.getColumn()].first = activeState.first;
+							distances[trans.getColumn()].second = distance;
+							activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
 						}
 					}
 				}
@@ -292,8 +292,8 @@ public:
 
 			// if there is a terminal state that is an initial state then prob == 1 and return
 			if(initStates.get(*target)){
-				distances[*target].first = *target;
-				distances[*target].second = (T) 1;
+				distances[*target].getColumn() = *target;
+				distances[*target].getValue() = (T) 1;
 				return;
 			}
 
@@ -302,19 +302,19 @@ public:
 				//only use if allowed and not in subsys and not terminal
 				if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) {
 					//new state?
-					if(distances[*iter].second == (T) -1) {
+					if(distances[*iter].getValue() == (T) -1) {
 						// save as discovered and push into active set
-						distances[*iter].first = *target;												//successor
-						distances[*iter].second = transMat.getValue(*iter, *target);					//prob of shortest path
+						distances[*iter].getColumn() = *target;												//successor
+						distances[*iter].getValue() = transMat.getValue(*iter, *target);					//prob of shortest path
 
 						activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter]));		//prob of reaching some terminal state from pred.
 					}
 					else {
 						// state was already discovered
 						// is this the better transition?
-						if(distances[*iter].second > transMat.getValue(*iter, *target)) {
-							distances[*iter].first = *target;
-							distances[*iter].second = transMat.getValue(*iter, *target);
+						if(distances[*iter].getValue() > transMat.getValue(*iter, *target)) {
+							distances[*iter].getColumn() = *target;
+							distances[*iter].getValue() = transMat.getValue(*iter, *target);
 						}
 					}
 				}
@@ -328,19 +328,19 @@ public:
 				//only use if allowed and not in subsys and not terminal
 				if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) {
 					//new state?
-					if(distances[*iter].second == (T) -1) {
+					if(distances[*iter].getValue() == (T) -1) {
 						// save as discovered and push into active set
-						distances[*iter].first = *sysState;												//successor
-						distances[*iter].second = transMat.getValue(*iter, *sysState);					//prob of shortest path
+						distances[*iter].getColumn() = *sysState;												//successor
+						distances[*iter].getValue() = transMat.getValue(*iter, *sysState);					//prob of shortest path
 
 						activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter]));		//prob of reaching some terminal state from pred.
 					}
 					else {
 						// state was already discovered
 						// is this the better transition?
-						if(distances[*iter].second > transMat.getValue(*iter, *sysState)) {
-							distances[*iter].first = *sysState;
-							distances[*iter].second = transMat.getValue(*iter, *sysState);
+						if(distances[*iter].getValue() > transMat.getValue(*iter, *sysState)) {
+							distances[*iter].getColumn() = *sysState;
+							distances[*iter].getValue() = transMat.getValue(*iter, *sysState);
 						}
 					}
 				}
@@ -355,7 +355,7 @@ public:
 		while(!activeSet.empty()) {
 			// copy here since using a reference leads to segfault
 			state = *(--activeSet.end());
-			activeState = state.first;
+			activeState = state.getColumn();
 			activeSet.erase(--activeSet.end());
 
 			//stop on the first subsys/init state
@@ -368,19 +368,19 @@ public:
 					//only if transition is not "virtual" and no selfloop
 					if(*iter != activeState && transMat.getValue(*iter, activeState) != (T) 0) {
 						//new state?
-						if(distances[*iter].second == (T) -1) {
+						if(distances[*iter].getValue() == (T) -1) {
 							// save as discovered and push into active set
-							distances[*iter].first = activeState;
-							distances[*iter].second = transMat.getValue(*iter, activeState) * distances[activeState].second;
+							distances[*iter].getColumn() = activeState;
+							distances[*iter].getValue() = transMat.getValue(*iter, activeState) * distances[activeState].getValue();
 
 							activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter]));
 						}
 						else {
 							// state was already discovered
 							// is this the better transition?
-							if(distances[*iter].second < transMat.getValue(*iter, activeState) * distances[activeState].second) {
-								distances[*iter].first = activeState;
-								distances[*iter].second = transMat.getValue(*iter, activeState) * distances[activeState].second;
+							if(distances[*iter].getValue() < transMat.getValue(*iter, activeState) * distances[activeState].getValue()) {
+								distances[*iter].getColumn() = activeState;
+								distances[*iter].getValue() = transMat.getValue(*iter, activeState) * distances[activeState].getValue();
 							}
 						}
 					}
@@ -389,15 +389,15 @@ public:
 		}
 
 		//get path probability
-		probability = distances[activeState].second;
+		probability = distances[activeState].getValue();
 		if(probability == (T) -1) probability = 1;
 
 		// iterate over the successors until reaching the end of the finite path
 		shortestPath.push_back(activeState);
-		activeState = distances[activeState].first;
+		activeState = distances[activeState].getColumn();
 		while(!terminalStates.get(activeState) && !subSysStates.get(activeState)) {
 			shortestPath.push_back(activeState);
-			activeState = distances[activeState].first;
+			activeState = distances[activeState].getColumn();
 		}
 		shortestPath.push_back(activeState);
 	}
@@ -482,7 +482,7 @@ public:
 		shortestPath.push_back(bestIndex);
 
 		//At last compensate for the distance between init and source state
-		probability = itSearch ? probability : probability / itDistances[bestIndex].second;
+		probability = itSearch ? probability : probability / itDistances[bestIndex].first;
 	}
 
 private:
diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
index a4cd0844a..aab76f807 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
@@ -103,10 +103,10 @@ namespace storm {
                     for (auto state : markovianNonGoalStates) {
                         for (auto& element : aMarkovian.getRow(rowIndex)) {
                             ValueType eTerm = std::exp(-exitRates[state] * delta);
-                            if (element.first == rowIndex) {
-                                element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second + eTerm;
+                            if (element.getColumn() == rowIndex) {
+                                element.getValue() = (storm::utility::constantOne<ValueType>() - eTerm) * element.getValue() + eTerm;
                             } else {
-                                element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second;
+                                element.getValue() = (storm::utility::constantOne<ValueType>() - eTerm) * element.getValue();
                             }
                         }
                         ++rowIndex;
@@ -116,7 +116,7 @@ namespace storm {
                     rowIndex = 0;
                     for (auto state : markovianNonGoalStates) {
                         for (auto& element : aMarkovianToProbabilistic.getRow(rowIndex)) {
-                            element.second = (1 - std::exp(-exitRates[state] * delta)) * element.second;
+                            element.getValue() = (1 - std::exp(-exitRates[state] * delta)) * element.getValue();
                         }
                         ++rowIndex;
                     }
@@ -133,8 +133,8 @@ namespace storm {
                         bMarkovianFixed.push_back(storm::utility::constantZero<ValueType>());
                         
                         for (auto& element : transitionMatrix.getRowGroup(state)) {
-                            if (goalStates.get(element.first)) {
-                                bMarkovianFixed.back() += (1 - std::exp(-exitRates[state] * delta)) * element.second;
+                            if (goalStates.get(element.getColumn())) {
+                                bMarkovianFixed.back() += (1 - std::exp(-exitRates[state] * delta)) * element.getValue();
                             }
                         }
                     }
@@ -314,13 +314,13 @@ namespace storm {
                             b.push_back(storm::utility::constantZero<ValueType>());
                             
                             for (auto element : transitionMatrix.getRow(choice)) {
-                                if (statesNotContainedInAnyMec.get(element.first)) {
+                                if (statesNotContainedInAnyMec.get(element.getColumn())) {
                                     // If the target state is not contained in an MEC, we can copy over the entry.
-                                    sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second);
+                                    sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.getColumn()], element.getValue());
                                 } else {
                                     // If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector
                                     // so that we are able to write the cumulative probability to the MEC into the matrix.
-                                    auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second;
+                                    auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.getColumn()]] += element.getValue();
                                 }
                             }
                             
@@ -350,13 +350,13 @@ namespace storm {
                                     b.push_back(storm::utility::constantZero<ValueType>());
 
                                     for (auto element : transitionMatrix.getRow(choice)) {
-                                        if (statesNotContainedInAnyMec.get(element.first)) {
+                                        if (statesNotContainedInAnyMec.get(element.getColumn())) {
                                             // If the target state is not contained in an MEC, we can copy over the entry.
-                                            sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second);
+                                            sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.getColumn()], element.getValue());
                                         } else {
                                             // If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector
                                             // so that we are able to write the cumulative probability to the MEC into the matrix.
-                                            auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second;
+                                            auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.getColumn()]] += element.getValue();
                                         }
                                     }
                                     
@@ -453,8 +453,8 @@ namespace storm {
                             coefficients.push_back(1);
                             
                             for (auto element : transitionMatrix.getRow(nondeterministicChoiceIndices[state])) {
-                                variables.push_back(stateToVariableIndexMap.at(element.first));
-                                coefficients.push_back(-element.second);
+                                variables.push_back(stateToVariableIndexMap.at(element.getColumn()));
+                                coefficients.push_back(-element.getValue());
                             }
                             
                             variables.push_back(lraValueVariableIndex);
@@ -472,8 +472,8 @@ namespace storm {
                                 coefficients.push_back(1);
                                 
                                 for (auto element : transitionMatrix.getRow(choice)) {
-                                    variables.push_back(stateToVariableIndexMap.at(element.first));
-                                    coefficients.push_back(-element.second);
+                                    variables.push_back(stateToVariableIndexMap.at(element.getColumn()));
+                                    coefficients.push_back(-element.getValue());
                                 }
                                 
                                 solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, storm::utility::constantZero<ValueType>());
diff --git a/src/models/AbstractDeterministicModel.h b/src/models/AbstractDeterministicModel.h
index c72b914de..88e0d1006 100644
--- a/src/models/AbstractDeterministicModel.h
+++ b/src/models/AbstractDeterministicModel.h
@@ -87,9 +87,9 @@ class AbstractDeterministicModel: public AbstractModel<T> {
             for (uint_fast64_t i = 0; i < this->transitionMatrix.getRowCount(); ++i, ++rowIt) {
                 typename storm::storage::SparseMatrix<T>::const_rows row = this->transitionMatrix.getRow(i);
                 for (auto const& transition : row) {
-                    if (transition.second != storm::utility::constantZero<T>()) {
-                        if (subsystem == nullptr || subsystem->get(transition.first)) {
-                            outStream << "\t" << i << " -> " << transition.first << " [ label= \"" << transition.second << "\" ];" << std::endl;
+                    if (transition.getValue() != storm::utility::constantZero<T>()) {
+                        if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
+                            outStream << "\t" << i << " -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ];" << std::endl;
                         }
                     }
                 }
diff --git a/src/models/AbstractNondeterministicModel.h b/src/models/AbstractNondeterministicModel.h
index 0058377a6..3a738cbe6 100644
--- a/src/models/AbstractNondeterministicModel.h
+++ b/src/models/AbstractNondeterministicModel.h
@@ -189,8 +189,8 @@ namespace storm {
             
                         // Now draw all probabilitic arcs that belong to this nondeterminstic choice.
                         for (auto const& transition : row) {
-                            if (subsystem == nullptr || subsystem->get(transition.first)) {
-                                outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.first << " [ label= \"" << transition.second << "\" ]";
+                            if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
+                                outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ]";
                                 
                                 // If we were given a scheduler to highlight, we do so now.
                                 if (scheduler != nullptr) {
diff --git a/src/models/Dtmc.h b/src/models/Dtmc.h
index b599774f9..eb0e669dd 100644
--- a/src/models/Dtmc.h
+++ b/src/models/Dtmc.h
@@ -170,7 +170,7 @@ public:
 		for(uint_fast64_t row = 0; row < origMat.getRowCount(); ++row) {
 			if(subSysStates.get(row)){
 				for(auto const& entry : origMat.getRow(row)) {
-					if(subSysStates.get(entry.first)) {
+					if(subSysStates.get(entry.getColumn())) {
 						subSysTransitionCount++;	
 					} 
 				}
@@ -198,10 +198,10 @@ public:
 			if(subSysStates.get(row)){
 				// Transfer transitions
 				for(auto& entry : origMat.getRow(row)) {
-					if(subSysStates.get(entry.first)) {
-						newMatBuilder.addNextValue(newRow, stateMapping[entry.first], entry.second);
+					if(subSysStates.get(entry.getColumn())) {
+						newMatBuilder.addNextValue(newRow, stateMapping[entry.getColumn()], entry.getValue());
 					} else {
-						rest += entry.second;
+						rest += entry.getValue();
 					}
 				}
 
@@ -251,8 +251,8 @@ public:
 				if(subSysStates.get(row)){
 					// Transfer transition rewards
 					for(auto& entry : this->getTransitionRewardMatrix().getRow(row)) {
-						if(subSysStates.get(entry.first)) {
-							newTransRewardsBuilder.addNextValue(newRow, stateMapping[entry.first], entry.second);
+						if(subSysStates.get(entry.getColumn())) {
+							newTransRewardsBuilder.addNextValue(newRow, stateMapping[entry.getColumn()], entry.getValue());
 						}
 					}
 
diff --git a/src/models/MarkovAutomaton.h b/src/models/MarkovAutomaton.h
index 22b6ab13f..89ce7ccee 100644
--- a/src/models/MarkovAutomaton.h
+++ b/src/models/MarkovAutomaton.h
@@ -147,7 +147,7 @@ namespace storm {
 
                         for (uint_fast64_t row = this->getTransitionMatrix().getRowGroupIndices()[state] + (this->isHybridState(state) ? 1 : 0); row < this->getTransitionMatrix().getRowGroupIndices()[state + 1]; ++row) {
                             for (auto const& entry : this->transitionMatrix.getRow(row)) {
-                                newTransitionMatrixBuilder.addNextValue(currentChoice, entry.first, entry.second);
+                                newTransitionMatrixBuilder.addNextValue(currentChoice, entry.getColumn(), entry.getValue());
                             }
                             ++currentChoice;
                         }
@@ -220,8 +220,8 @@ namespace storm {
                     
                     // Now draw all probabilitic arcs that belong to this nondeterminstic choice.
                     for (auto const& transition : row) {
-                        if (subsystem == nullptr || subsystem->get(transition.first)) {
-                            outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.first << " [ label= \"" << transition.second << "\" ]";
+                        if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
+                            outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ]";
                             
                             // If we were given a scheduler to highlight, we do so now.
                             if (scheduler != nullptr) {
@@ -237,8 +237,8 @@ namespace storm {
                     } else {
                         // In this case we are emitting a Markovian choice, so draw the arrows directly to the target states.
                         for (auto const& transition : row) {
-                            if (subsystem == nullptr || subsystem->get(transition.first)) {
-                                outStream << "\t\"" << state << "\" -> " << transition.first << " [ label= \"" << transition.second << " (" << this->exitRates[state] << ")\" ]";
+                            if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
+                                outStream << "\t\"" << state << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << " (" << this->exitRates[state] << ")\" ]";
                             }
                         }
                     }
@@ -259,7 +259,7 @@ namespace storm {
             void turnRatesToProbabilities() {
                 for (auto state : this->markovianStates) {
                     for (auto& transition : this->transitionMatrix.getRowGroup(state)) {
-                        transition.second /= this->exitRates[state];
+                        transition.getValue() /= this->exitRates[state];
                     }
                 }
             }
diff --git a/src/storage/MaximalEndComponentDecomposition.cpp b/src/storage/MaximalEndComponentDecomposition.cpp
index 56ebbd34c..0f6a44f65 100644
--- a/src/storage/MaximalEndComponentDecomposition.cpp
+++ b/src/storage/MaximalEndComponentDecomposition.cpp
@@ -88,7 +88,7 @@ namespace storm {
                             for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) {
                                 bool choiceContainedInMEC = true;
                                 for (auto const& entry : transitionMatrix.getRow(choice)) {
-                                    if (scc.find(entry.first) == scc.end()) {
+                                    if (scc.find(entry.getColumn()) == scc.end()) {
                                         choiceContainedInMEC = false;
                                         break;
                                     }
@@ -116,8 +116,8 @@ namespace storm {
                         statesToCheck.clear();
                         for (auto state : statesToRemove) {
                             for (auto const& entry : backwardTransitions.getRow(state)) {
-                                if (scc.find(entry.first) != scc.end()) {
-                                    statesToCheck.set(entry.first);
+                                if (scc.find(entry.getColumn()) != scc.end()) {
+                                    statesToCheck.set(entry.getColumn());
                                 }
                             }
                         }
@@ -154,7 +154,7 @@ namespace storm {
                     for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) {
                         bool choiceContained = true;
                         for (auto const& entry : transitionMatrix.getRow(choice)) {
-                            if (mecStateSet.find(entry.first) == mecStateSet.end()) {
+                            if (mecStateSet.find(entry.getColumn()) == mecStateSet.end()) {
                                 choiceContained = false;
                                 break;
                             }
diff --git a/src/storage/SparseMatrix.cpp b/src/storage/SparseMatrix.cpp
index e4d719006..c6bfd0214 100644
--- a/src/storage/SparseMatrix.cpp
+++ b/src/storage/SparseMatrix.cpp
@@ -17,6 +17,41 @@ extern log4cplus::Logger logger;
 namespace storm {
     namespace storage {
         
+        template<typename T>
+        MatrixEntry<T>::MatrixEntry(uint_fast64_t column, T value) : entry(column, value) {
+            // Intentionally left empty.
+        }
+        
+        template<typename T>
+        MatrixEntry<T>::MatrixEntry(std::pair<uint_fast64_t, T>&& pair) : entry(std::move(pair)) {
+            // Intentionally left empty.
+        }
+        
+        template<typename T>
+        uint_fast64_t const& MatrixEntry<T>::getColumn() const {
+            return this->entry.first;
+        }
+        
+        template<typename T>
+        uint_fast64_t& MatrixEntry<T>::getColumn() {
+            return this->entry.first;
+        }
+        
+        template<typename T>
+        T const& MatrixEntry<T>::getValue() const {
+            return this->entry.second;
+        }
+        
+        template<typename T>
+        T& MatrixEntry<T>::getValue() {
+            return this->entry.second;
+        }
+        
+        template<typename T>
+        std::pair<uint_fast64_t, T> const& MatrixEntry<T>::getColumnValuePair() const {
+            return this->entry;
+        }
+        
         template<typename T>
         SparseMatrixBuilder<T>::SparseMatrixBuilder(uint_fast64_t rows, uint_fast64_t columns, uint_fast64_t entries, bool hasCustomRowGrouping, uint_fast64_t rowGroups) : rowCountSet(rows != 0), rowCount(rows), columnCountSet(columns != 0), columnCount(columns), entryCount(entries), hasCustomRowGrouping(hasCustomRowGrouping), rowGroupCountSet(rowGroups != 0), rowGroupCount(rowGroups), rowGroupIndices(), storagePreallocated(rows != 0 && columns != 0 && entries != 0), columnsAndValues(), rowIndications(), currentEntryCount(0), lastRow(0), lastColumn(0), currentRowGroup(0) {
             this->prepareInternalStorage();
@@ -168,7 +203,7 @@ namespace storm {
         void SparseMatrixBuilder<T>::prepareInternalStorage() {
             // Only allocate the memory for the matrix contents if the dimensions of the matrix are already known.
             if (storagePreallocated) {
-                columnsAndValues = std::vector<std::pair<uint_fast64_t, T>>(entryCount, std::make_pair(0, storm::utility::constantZero<T>()));
+                columnsAndValues = std::vector<MatrixEntry<T>>(entryCount, MatrixEntry<T>(0, storm::utility::constantZero<T>()));
                 rowIndications = std::vector<uint_fast64_t>(rowCount + 1, 0);
             } else {
                 rowIndications.push_back(0);
@@ -236,18 +271,18 @@ namespace storm {
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t> const& rowIndications, std::vector<std::pair<uint_fast64_t, T>> const& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), nonzeroEntryCount(0), columnsAndValues(columnsAndValues), rowIndications(rowIndications), rowGroupIndices(rowGroupIndices) {
+        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t> const& rowIndications, std::vector<MatrixEntry<T>> const& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), nonzeroEntryCount(0), columnsAndValues(columnsAndValues), rowIndications(rowIndications), rowGroupIndices(rowGroupIndices) {
             for (auto const& element : *this) {
-                if (element.second != storm::utility::constantZero<T>()) {
+                if (element.getValue() != storm::utility::constantZero<T>()) {
                     ++this->nonzeroEntryCount;
                 }
             }
         }
         
         template<typename T>
-        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t>&& rowIndications, std::vector<std::pair<uint_fast64_t, T>>&& columnsAndValues, std::vector<uint_fast64_t>&& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), nonzeroEntryCount(0), columnsAndValues(std::move(columnsAndValues)), rowIndications(std::move(rowIndications)), rowGroupIndices(std::move(rowGroupIndices)) {
+        SparseMatrix<T>::SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t>&& rowIndications, std::vector<MatrixEntry<T>>&& columnsAndValues, std::vector<uint_fast64_t>&& rowGroupIndices) : rowCount(rowIndications.size() - 1), columnCount(columnCount), entryCount(columnsAndValues.size()), nonzeroEntryCount(0), columnsAndValues(std::move(columnsAndValues)), rowIndications(std::move(rowIndications)), rowGroupIndices(std::move(rowGroupIndices)) {
             for (auto const& element : *this) {
-                if (element.second != storm::utility::constantZero<T>()) {
+                if (element.getValue() != storm::utility::constantZero<T>()) {
                     ++this->nonzeroEntryCount;
                 }
             }
@@ -304,17 +339,17 @@ namespace storm {
             for (uint_fast64_t row = 0; row < this->getRowCount(); ++row) {
                 for (const_iterator it1 = this->begin(row), ite1 = this->end(row), it2 = other.begin(row), ite2 = other.end(row); it1 != ite1 && it2 != ite2; ++it1, ++it2) {
                     // Skip over all zero entries in both matrices.
-                    while (it1 != ite1 && it1->second == storm::utility::constantZero<T>()) {
+                    while (it1 != ite1 && it1->getValue() == storm::utility::constantZero<T>()) {
                         ++it1;
                     }
-                    while (it2 != ite2 && it2->second == storm::utility::constantZero<T>()) {
+                    while (it2 != ite2 && it2->getValue() == storm::utility::constantZero<T>()) {
                         ++it2;
                     }
                     if ((it1 == ite1) || (it2 == ite2)) {
                         equalityResult = (it1 == ite1) ^ (it2 == ite2);
                         break;
                     } else {
-                        if (it1->first != it2->first || it1->second != it2->second) {
+                        if (it1->getColumn() != it2->getColumn() || it1->getValue() != it2->getValue()) {
                             equalityResult = false;
                             break;
                         }
@@ -389,12 +424,12 @@ namespace storm {
             
             // If there is at least one entry in this row, we can just set it to one, modify its column value to the
             // one given by the parameter and set all subsequent elements of this row to zero.
-            columnValuePtr->first = column;
-            columnValuePtr->second = storm::utility::constantOne<T>();
+            columnValuePtr->getColumn() = column;
+            columnValuePtr->getValue() = storm::utility::constantOne<T>();
             ++columnValuePtr;
             for (; columnValuePtr != columnValuePtrEnd; ++columnValuePtr) {
-                columnValuePtr->first = 0;
-                columnValuePtr->second = storm::utility::constantZero<T>();
+                columnValuePtr->getColumn() = 0;
+                columnValuePtr->getValue() = storm::utility::constantZero<T>();
             }
         }
         
@@ -402,8 +437,8 @@ namespace storm {
         T SparseMatrix<T>::getConstrainedRowSum(uint_fast64_t row, storm::storage::BitVector const& constraint) const {
             T result(0);
             for (const_iterator it = this->begin(row), ite = this->end(row); it != ite; ++it) {
-                if (constraint.get(it->first)) {
-                    result += it->second;
+                if (constraint.get(it->getColumn())) {
+                    result += it->getValue();
                 }
             }
             return result;
@@ -457,10 +492,10 @@ namespace storm {
                     bool foundDiagonalElement = false;
                     
                     for (const_iterator it = this->begin(i), ite = this->end(i); it != ite; ++it) {
-                        if (columnConstraint.get(it->first)) {
+                        if (columnConstraint.get(it->getColumn())) {
                             ++subEntries;
                             
-                            if (index == it->first) {
+                            if (index == it->getColumn()) {
                                 foundDiagonalElement = true;
                             }
                         }
@@ -507,14 +542,14 @@ namespace storm {
                     bool insertedDiagonalElement = false;
                     
                     for (const_iterator it = this->begin(i), ite = this->end(i); it != ite; ++it) {
-                        if (columnConstraint.get(it->first)) {
-                            if (index == it->first) {
+                        if (columnConstraint.get(it->getColumn())) {
+                            if (index == it->getColumn()) {
                                 insertedDiagonalElement = true;
-                            } else if (insertDiagonalEntries && !insertedDiagonalElement && it->first > index) {
+                            } else if (insertDiagonalEntries && !insertedDiagonalElement && it->getColumn() > index) {
                                 matrixBuilder.addNextValue(rowCount, bitsSetBeforeIndex[index], storm::utility::constantZero<T>());
                                 insertedDiagonalElement = true;
                             }
-                            matrixBuilder.addNextValue(rowCount, bitsSetBeforeIndex[it->first], it->second);
+                            matrixBuilder.addNextValue(rowCount, bitsSetBeforeIndex[it->getColumn()], it->getValue());
                         }
                     }
                     if (insertDiagonalEntries && !insertedDiagonalElement) {
@@ -540,7 +575,7 @@ namespace storm {
                 // Iterate through that row and count the number of slots we have to reserve for copying.
                 bool foundDiagonalElement = false;
                 for (const_iterator it = this->begin(rowToCopy), ite = this->end(rowToCopy); it != ite; ++it) {
-                    if (it->first == rowGroupIndex) {
+                    if (it->getColumn() == rowGroupIndex) {
                         foundDiagonalElement = true;
                     }
                     ++subEntries;
@@ -562,13 +597,13 @@ namespace storm {
                 // there is no entry yet.
                 bool insertedDiagonalElement = false;
                 for (const_iterator it = this->begin(rowToCopy), ite = this->end(rowToCopy); it != ite; ++it) {
-                    if (it->first == rowGroupIndex) {
+                    if (it->getColumn() == rowGroupIndex) {
                         insertedDiagonalElement = true;
-                    } else if (insertDiagonalEntries && !insertedDiagonalElement && it->first > rowGroupIndex) {
+                    } else if (insertDiagonalEntries && !insertedDiagonalElement && it->getColumn() > rowGroupIndex) {
                         matrixBuilder.addNextValue(rowGroupIndex, rowGroupIndex, storm::utility::constantZero<T>());
                         insertedDiagonalElement = true;
                     }
-                    matrixBuilder.addNextValue(rowGroupIndex, it->first, it->second);
+                    matrixBuilder.addNextValue(rowGroupIndex, it->getColumn(), it->getValue());
                 }
                 if (insertDiagonalEntries && !insertedDiagonalElement) {
                     matrixBuilder.addNextValue(rowGroupIndex, rowGroupIndex, storm::utility::constantZero<T>());
@@ -586,13 +621,13 @@ namespace storm {
             uint_fast64_t entryCount = this->getEntryCount();
             
             std::vector<uint_fast64_t> rowIndications(rowCount + 1);
-            std::vector<std::pair<uint_fast64_t, T>> columnsAndValues(entryCount);
+            std::vector<MatrixEntry<T>> columnsAndValues(entryCount);
             
             // First, we need to count how many entries each column has.
             for (uint_fast64_t group = 0; group < columnCount; ++group) {
                 for (auto const& transition : joinGroups ? this->getRowGroup(group) : this->getRow(group)) {
-                    if (transition.second != storm::utility::constantZero<T>()) {
-                        ++rowIndications[transition.first + 1];
+                    if (transition.getValue() != storm::utility::constantZero<T>()) {
+                        ++rowIndications[transition.getColumn() + 1];
                     }
                 }
             }
@@ -610,9 +645,9 @@ namespace storm {
             // Now we are ready to actually fill in the values of the transposed matrix.
             for (uint_fast64_t group = 0; group < columnCount; ++group) {
                 for (auto const& transition : joinGroups ? this->getRowGroup(group) : this->getRow(group)) {
-                    if (transition.second != storm::utility::constantZero<T>()) {
-                        columnsAndValues[nextIndices[transition.first]] = std::make_pair(group, transition.second);
-                        nextIndices[transition.first]++;
+                    if (transition.getValue() != storm::utility::constantZero<T>()) {
+                        columnsAndValues[nextIndices[transition.getColumn()]] = std::make_pair(group, transition.getValue());
+                        nextIndices[transition.getColumn()]++;
                     }
                 }
             }
@@ -641,8 +676,8 @@ namespace storm {
             bool foundDiagonalElement = false;
             for (uint_fast64_t group = 0; group < this->getRowGroupCount(); ++group) {
                 for (auto& entry : this->getRowGroup(group)) {
-                    if (entry.first == group) {
-                        entry.second = one - entry.second;
+                    if (entry.getColumn() == group) {
+                        entry.getValue() = one - entry.getValue();
                         foundDiagonalElement = true;
                     }
                 }
@@ -659,8 +694,8 @@ namespace storm {
             // Iterate over all row groups and negate all the elements that are not on the diagonal.
             for (uint_fast64_t group = 0; group < this->getRowGroupCount(); ++group) {
                 for (auto& entry : this->getRowGroup(group)) {
-                    if (entry.first != group) {
-                        entry.second = -entry.second;
+                    if (entry.getColumn() != group) {
+                        entry.getValue() = -entry.getValue();
                     }
                 }
             }
@@ -671,8 +706,8 @@ namespace storm {
             // Iterate over all rows and negate all the elements that are not on the diagonal.
             for (uint_fast64_t group = 0; group < this->getRowGroupCount(); ++group) {
                 for (auto& entry : this->getRowGroup(group)) {
-                    if (entry.first == group) {
-                        entry.second = storm::utility::constantZero<T>();
+                    if (entry.getColumn() == group) {
+                        entry.getValue() = storm::utility::constantZero<T>();
                     }
                 }
             }
@@ -695,9 +730,9 @@ namespace storm {
                 // to invert the entry.
                 T diagonalValue = storm::utility::constantZero<T>();
                 for (const_iterator it = this->begin(rowNumber), ite = this->end(rowNumber); it != ite; ++it) {
-                    if (it->first == rowNumber) {
-                        diagonalValue += it->second;
-                    } else if (it->first > rowNumber) {
+                    if (it->getColumn() == rowNumber) {
+                        diagonalValue += it->getValue();
+                    } else if (it->getColumn() > rowNumber) {
                         break;
                     }
                 }
@@ -716,13 +751,13 @@ namespace storm {
             // add the result to the corresponding position in the vector.
             for (uint_fast64_t row = 0; row < rowCount && row < otherMatrix.rowCount; ++row) {
                 for (const_iterator it1 = this->begin(row), ite1 = this->end(row), it2 = otherMatrix.begin(row), ite2 = otherMatrix.end(row); it1 != ite1 && it2 != ite2; ++it1) {
-                    if (it1->first < it2->first) {
+                    if (it1->getColumn() < it2->getColumn()) {
                         continue;
                     } else {
                         // If the precondition of this method (i.e. that the given matrix is a submatrix
                         // of the current one) was fulfilled, we know now that the two elements are in
                         // the same column, so we can multiply and add them to the row sum vector.
-                        result[row] += it2->second * it1->second;
+                        result[row] += it2->getValue() * it1->getValue();
                         ++it2;
                     }
                 }
@@ -750,7 +785,7 @@ namespace storm {
                                       *resultIterator = storm::utility::constantZero<T>();
                                       
                                       for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) {
-                                          *resultIterator += it->second * vector[it->first];
+                                          *resultIterator += it->getValue() * vector[it->getColumn()];
                                       }
                                   }
                               });
@@ -765,7 +800,7 @@ namespace storm {
                 *resultIterator = storm::utility::constantZero<T>();
                 
                 for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) {
-                    *resultIterator += it->second * vector[it->first];
+                    *resultIterator += it->getValue() * vector[it->getColumn()];
                 }
             }
 #endif
@@ -776,7 +811,7 @@ namespace storm {
             uint_fast64_t size = sizeof(*this);
             
             // Add size of columns and values.
-            size += sizeof(std::pair<uint_fast64_t, T>) * columnsAndValues.capacity();
+            size += sizeof(MatrixEntry<T>) * columnsAndValues.capacity();
             
             // Add row_indications size.
             size += sizeof(uint_fast64_t) * rowIndications.capacity();
@@ -848,7 +883,7 @@ namespace storm {
         T SparseMatrix<T>::getRowSum(uint_fast64_t row) const {
             T sum = storm::utility::constantZero<T>();
             for (const_iterator it = this->begin(row), ite = this->end(row); it != ite; ++it) {
-                sum += it->second;
+                sum += it->getValue();
             }
             return sum;
         }
@@ -864,10 +899,10 @@ namespace storm {
             for (uint_fast64_t row = 0; row < this->getRowCount(); ++row) {
                 for (const_iterator it1 = this->begin(row), ite1 = this->end(row), it2 = matrix.begin(row), ite2 = matrix.end(row); it1 != ite1; ++it1) {
                     // Skip over all entries of the other matrix that are before the current entry in the current matrix.
-                    while (it2 != ite2 && it2->first < it1->first) {
+                    while (it2 != ite2 && it2->getColumn() < it1->getColumn()) {
                         ++it2;
                     }
-                    if (it2 == ite2 || it1->first != it2->first) {
+                    if (it2 == ite2 || it1->getColumn() != it2->getColumn()) {
                         return false;
                     }
                 }
@@ -894,8 +929,8 @@ namespace storm {
                     out << i << "\t(\t";
                     uint_fast64_t currentRealIndex = 0;
                     while (currentRealIndex < matrix.columnCount) {
-                        if (nextIndex < matrix.rowIndications[i + 1] && currentRealIndex == matrix.columnsAndValues[nextIndex].first) {
-                            out << matrix.columnsAndValues[nextIndex].second << "\t";
+                        if (nextIndex < matrix.rowIndications[i + 1] && currentRealIndex == matrix.columnsAndValues[nextIndex].getColumn()) {
+                            out << matrix.columnsAndValues[nextIndex].getValue() << "\t";
                             ++nextIndex;
                         } else {
                             out << "0\t";
@@ -930,10 +965,12 @@ namespace storm {
             return result;
         }
         
-        // Explicitly instantiate the builder and the matrix.
+        // Explicitly instantiate the entry, builder and the matrix.
+        template class MatrixEntry<double>;
         template class SparseMatrixBuilder<double>;
         template class SparseMatrix<double>;
         template std::ostream& operator<<(std::ostream& out, SparseMatrix<double> const& matrix);
+        template class MatrixEntry<int>;
         template class SparseMatrixBuilder<int>;
         template class SparseMatrix<int>;
         template std::ostream& operator<<(std::ostream& out, SparseMatrix<int> const& matrix);
diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h
index b8b8b80d3..b60cbdc16 100644
--- a/src/storage/SparseMatrix.h
+++ b/src/storage/SparseMatrix.h
@@ -8,6 +8,7 @@
 
 #include "src/storage/BitVector.h"
 #include "src/utility/constants.h"
+#include "src/utility/OsDetection.h"
 
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/exceptions/OutOfRangeException.h"
@@ -27,6 +28,83 @@ namespace storm {
         // Forward declare matrix class.
         template<typename T> class SparseMatrix;
         
+        template<typename T>
+        class MatrixEntry {
+        public:
+            /*!
+             * Constructs a matrix entry with the given column and value.
+             *
+             * @param column The column of the matrix entry.
+             * @param value The value of the matrix entry.
+             */
+            MatrixEntry(uint_fast64_t column, T value);
+            
+            /*!
+             * Move-constructs the matrix entry fro the given column-value pair.
+             *
+             * @param pair The column-value pair from which to move-construct the matrix entry.
+             */
+            MatrixEntry(std::pair<uint_fast64_t, T>&& pair);
+            
+            MatrixEntry() = default;
+            MatrixEntry(MatrixEntry const& other) = default;
+            MatrixEntry& operator=(MatrixEntry const& other) = default;
+#ifndef WINDOWS
+            MatrixEntry(MatrixEntry&& other) = default;
+            MatrixEntry& operator=(MatrixEntry&& other) = default;
+#endif
+            
+            /*!
+             * Retrieves the column of the matrix entry.
+             *
+             * @return The column of the matrix entry.
+             */
+            uint_fast64_t const& getColumn() const;
+            
+            /*!
+             * Retrieves the column of the matrix entry.
+             *
+             * @return The column of the matrix entry.
+             */
+            uint_fast64_t& getColumn();
+            
+            /*!
+             * Retrieves the value of the matrix entry.
+             *
+             * @return The value of the matrix entry.
+             */
+            T const& getValue() const;
+
+            /*!
+             * Retrieves the value of the matrix entry.
+             *
+             * @return The value of the matrix entry.
+             */
+            T& getValue();
+            
+            /*!
+             * Retrieves a pair of column and value that characterizes this entry.
+             *
+             * @return A column-value pair that characterizes this entry.
+             */
+            std::pair<uint_fast64_t, T> const& getColumnValuePair() const;
+            
+        private:
+            // The actual matrix entry.
+            std::pair<uint_fast64_t, T> entry;
+        };
+        
+        /*!
+         * Computes the hash value of a matrix entry.
+         */
+        template<typename T>
+        std::size_t hash_value(MatrixEntry<T> const& matrixEntry) {
+            std::size_t seed = 0;
+            boost::hash_combine(seed, matrixEntry.getColumn());
+            boost::hash_combine(seed, matrixEntry.getValue());
+            return seed;
+        }
+        
         /*!
          * A class that can be used to build a sparse matrix by adding value by value.
          */
@@ -128,7 +206,7 @@ namespace storm {
             bool storagePreallocated;
             
             // The storage for the columns and values of all entries in the matrix.
-            std::vector<std::pair<uint_fast64_t, T>> columnsAndValues;
+            std::vector<MatrixEntry<T>> columnsAndValues;
             
             // A vector containing the indices at which each given row begins. This index is to be interpreted as an
             // index in the valueStorage and the columnIndications vectors. Put differently, the values of the entries
@@ -175,8 +253,8 @@ namespace storm {
             friend class storm::adapters::EigenAdapter;
             friend class storm::adapters::StormAdapter;
             
-            typedef typename std::vector<std::pair<uint_fast64_t, T>>::iterator iterator;
-            typedef typename std::vector<std::pair<uint_fast64_t, T>>::const_iterator const_iterator;
+            typedef typename std::vector<MatrixEntry<T>>::iterator iterator;
+            typedef typename std::vector<MatrixEntry<T>>::const_iterator const_iterator;
             
             /*!
              * This class represents a number of consecutive rows of the matrix.
@@ -284,7 +362,7 @@ namespace storm {
              * @param columnsAndValues The vector containing the columns and values of the entries in the matrix.
              * @param rowGroupIndices The vector representing the row groups in the matrix.
              */
-            SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t> const& rowIndications, std::vector<std::pair<uint_fast64_t, T>> const& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupIndices);
+            SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t> const& rowIndications, std::vector<MatrixEntry<T>> const& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupIndices);
             
             /*!
              * Constructs a sparse matrix by moving the given contents.
@@ -294,7 +372,7 @@ namespace storm {
              * @param columnsAndValues The vector containing the columns and values of the entries in the matrix.
              * @param rowGroupIndices The vector representing the row groups in the matrix.
              */
-            SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t>&& rowIndications, std::vector<std::pair<uint_fast64_t, T>>&& columnsAndValues, std::vector<uint_fast64_t>&& rowGroupIndices);
+            SparseMatrix(uint_fast64_t columnCount, std::vector<uint_fast64_t>&& rowIndications, std::vector<MatrixEntry<T>>&& columnsAndValues, std::vector<uint_fast64_t>&& rowGroupIndices);
 
             /*!
              * Assigns the contents of the given matrix to the current one by deep-copying its contents.
@@ -662,7 +740,7 @@ namespace storm {
             uint_fast64_t nonzeroEntryCount;
             
             // The storage for the columns and values of all entries in the matrix.
-            std::vector<std::pair<uint_fast64_t, T>> columnsAndValues;
+            std::vector<MatrixEntry<T>> columnsAndValues;
             
             // A vector containing the indices at which each given row begins. This index is to be interpreted as an
             // index in the valueStorage and the columnIndications vectors. Put differently, the values of the entries
diff --git a/src/storage/StronglyConnectedComponentDecomposition.cpp b/src/storage/StronglyConnectedComponentDecomposition.cpp
index 6e9f08386..b14559bcb 100644
--- a/src/storage/StronglyConnectedComponentDecomposition.cpp
+++ b/src/storage/StronglyConnectedComponentDecomposition.cpp
@@ -114,33 +114,33 @@ namespace storm {
                 // Now, traverse all successors of the current state.
                 for(; successorIt != model.getRows(currentState).end(); ++successorIt) {
                     // Record if the current state has a self-loop if we are to drop naive SCCs later.
-                    if (dropNaiveSccs && currentState == successorIt->first) {
+                    if (dropNaiveSccs && currentState == successorIt->getColumn()) {
                         statesWithSelfloop.set(currentState, true);
                     }
                     
                     // If we have not visited the successor already, we need to perform the procedure recursively on the
                     // newly found state, but only if it belongs to the subsystem in which we are interested.
-                    if (subsystem.get(successorIt->first)) {
-                        if (!visitedStates.get(successorIt->first)) {
+                    if (subsystem.get(successorIt->getColumn())) {
+                        if (!visitedStates.get(successorIt->getColumn())) {
                             // Save current iterator position so we can continue where we left off later.
                             recursionIteratorStack.pop_back();
                             recursionIteratorStack.push_back(successorIt);
                             
                             // Put unvisited successor on top of our recursion stack and remember that.
-                            recursionStateStack.push_back(successorIt->first);
-                            statesInStack[successorIt->first] = true;
+                            recursionStateStack.push_back(successorIt->getColumn());
+                            statesInStack[successorIt->getColumn()] = true;
                             
                             // Also, put initial value for iterator on corresponding recursion stack.
-                            recursionIteratorStack.push_back(model.getRows(successorIt->first).begin());
+                            recursionIteratorStack.push_back(model.getRows(successorIt->getColumn()).begin());
                             
                             // Perform the actual recursion step in an iterative way.
                             goto recursionStepForward;
                             
                         recursionStepBackward:
-                            lowlinks[currentState] = std::min(lowlinks[currentState], lowlinks[successorIt->first]);
-                        } else if (tarjanStackStates.get(successorIt->first)) {
+                            lowlinks[currentState] = std::min(lowlinks[currentState], lowlinks[successorIt->getColumn()]);
+                        } else if (tarjanStackStates.get(successorIt->getColumn())) {
                             // Update the lowlink of the current state.
-                            lowlinks[currentState] = std::min(lowlinks[currentState], stateIndices[successorIt->first]);
+                            lowlinks[currentState] = std::min(lowlinks[currentState], stateIndices[successorIt->getColumn()]);
                         }
                     }
                 }
@@ -165,7 +165,7 @@ namespace storm {
                     if (onlyBottomSccs) {
                         for (auto const& state : scc) {
                             for (auto const& successor : model.getRows(state)) {
-                                if (scc.find(successor.first) == scc.end()) {
+                                if (scc.find(successor.getColumn()) == scc.end()) {
                                     isBottomScc = false;
                                     break;
                                 }
diff --git a/src/utility/counterexamples.h b/src/utility/counterexamples.h
index 23b5b372e..8b233e402 100644
--- a/src/utility/counterexamples.h
+++ b/src/utility/counterexamples.h
@@ -36,8 +36,8 @@ namespace storm {
 //                for (auto state : psiStates) {
 //                    analysisInformation[state] = boost::container::flat_set<uint_fast64_t>();
 //                    for (auto const& predecessorEntry : backwardTransitions.getRow(state)) {
-//                        if (predecessorEntry.first != state && !psiStates.get(predecessorEntry.first)) {
-//                            worklist.push(std::make_pair(predecessorEntry.first, state));
+//                        if (predecessorEntry.getColumn() != state && !psiStates.get(predecessorEntry.getColumn())) {
+//                            worklist.push(std::make_pair(predecessorEntry.getColumn(), state));
 //                        }
 //                    }
 //                }
@@ -57,7 +57,7 @@ namespace storm {
 //                        bool choiceTargetsTargetState = false;
 //                        
 //                        for (auto& entry : transitionMatrix.getRow(currentChoice)) {
-//                            if (entry.first == targetState) {
+//                            if (entry.getColumn() == targetState) {
 //                                choiceTargetsTargetState = true;
 //                                break;
 //                            }
@@ -79,8 +79,8 @@ namespace storm {
 //                    if (analysisInformation[currentState].size() != analysisInformationSizeBefore) {
 //                        for (auto& predecessorEntry : backwardTransitions.getRow(currentState)) {
 //                            // Only put the predecessor in the worklist if it's not already a target state.
-//                            if (!psiStates.get(predecessorEntry.first)) {
-//                                worklist.push(std::make_pair(predecessorEntry.first, currentState));
+//                            if (!psiStates.get(predecessorEntry.getColumn())) {
+//                                worklist.push(std::make_pair(predecessorEntry.getColumn(), currentState));
 //                            }
 //                        }
 //                    }
@@ -96,9 +96,9 @@ namespace storm {
                 for (auto state : psiStates) {
                     analysisInformation[state] = boost::container::flat_set<uint_fast64_t>();
                     for (auto const& predecessorEntry : backwardTransitions.getRow(state)) {
-                        if (predecessorEntry.first != state && !statesInWorkList.get(predecessorEntry.first) && !psiStates.get(predecessorEntry.first)) {
-                            worklist.push(predecessorEntry.first);
-                            statesInWorkList.set(predecessorEntry.first);
+                        if (predecessorEntry.getColumn() != state && !statesInWorkList.get(predecessorEntry.getColumn()) && !psiStates.get(predecessorEntry.getColumn())) {
+                            worklist.push(predecessorEntry.getColumn());
+                            statesInWorkList.set(predecessorEntry.getColumn());
                             markedStates.set(state);
                         }
                     }
@@ -116,7 +116,7 @@ namespace storm {
                         bool modifiedChoice = false;
                         
                         for (auto const& entry : transitionMatrix.getRow(currentChoice)) {
-                            if (markedStates.get(entry.first)) {
+                            if (markedStates.get(entry.getColumn())) {
                                 modifiedChoice = true;
                                 break;
                             }
@@ -127,9 +127,9 @@ namespace storm {
                         // and the choice labels.
                         if (modifiedChoice) {
                             for (auto const& entry : transitionMatrix.getRow(currentChoice)) {
-                                if (markedStates.get(entry.first)) {
+                                if (markedStates.get(entry.getColumn())) {
                                     boost::container::flat_set<uint_fast64_t> tmpIntersection;
-                                    std::set_intersection(analysisInformation[currentState].begin(), analysisInformation[currentState].end(), analysisInformation[entry.first].begin(), analysisInformation[entry.first].end(), std::inserter(tmpIntersection, tmpIntersection.begin()));
+                                    std::set_intersection(analysisInformation[currentState].begin(), analysisInformation[currentState].end(), analysisInformation[entry.getColumn()].begin(), analysisInformation[entry.getColumn()].end(), std::inserter(tmpIntersection, tmpIntersection.begin()));
                                     std::set_intersection(analysisInformation[currentState].begin(), analysisInformation[currentState].end(), choiceLabeling[currentChoice].begin(), choiceLabeling[currentChoice].end(), std::inserter(tmpIntersection, tmpIntersection.begin()));
                                     analysisInformation[currentState] = std::move(tmpIntersection);
                                 }
@@ -142,9 +142,9 @@ namespace storm {
                     if (analysisInformation[currentState].size() != analysisInformationSizeBefore) {
                         for (auto const& predecessorEntry : backwardTransitions.getRow(currentState)) {
                             // Only put the predecessor in the worklist if it's not already a target state.
-                            if (!psiStates.get(predecessorEntry.first) && !statesInWorkList.get(predecessorEntry.first)) {
-                                worklist.push(predecessorEntry.first);
-                                statesInWorkList.set(predecessorEntry.first);
+                            if (!psiStates.get(predecessorEntry.getColumn()) && !statesInWorkList.get(predecessorEntry.getColumn())) {
+                                worklist.push(predecessorEntry.getColumn());
+                                statesInWorkList.set(predecessorEntry.getColumn());
                             }
                         }
                         markedStates.set(currentState, true);
diff --git a/src/utility/graph.h b/src/utility/graph.h
index 01d0a7f4f..3d0d95fb1 100644
--- a/src/utility/graph.h
+++ b/src/utility/graph.h
@@ -79,16 +79,16 @@ namespace storm {
                     }
                     
                     for (typename storm::storage::SparseMatrix<T>::const_iterator entryIt = backwardTransitions.begin(currentState), entryIte = backwardTransitions.end(currentState); entryIt != entryIte; ++entryIt) {
-                        if (phiStates[entryIt->first] && (!statesWithProbabilityGreater0.get(entryIt->first) || (useStepBound && remainingSteps[entryIt->first] < currentStepBound - 1))) {
+                        if (phiStates[entryIt->getColumn()] && (!statesWithProbabilityGreater0.get(entryIt->getColumn()) || (useStepBound && remainingSteps[entryIt->getColumn()] < currentStepBound - 1))) {
                             // If we don't have a bound on the number of steps to take, just add the state to the stack.
                             if (!useStepBound) {
-                                statesWithProbabilityGreater0.set(entryIt->first, true);
-                                stack.push_back(entryIt->first);
+                                statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
+                                stack.push_back(entryIt->getColumn());
                             } else if (currentStepBound > 0) {
                                 // If there is at least one more step to go, we need to push the state and the new number of steps.
-                                remainingSteps[entryIt->first] = currentStepBound - 1;
-                                statesWithProbabilityGreater0.set(entryIt->first, true);
-                                stack.push_back(entryIt->first);
+                                remainingSteps[entryIt->getColumn()] = currentStepBound - 1;
+                                statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
+                                stack.push_back(entryIt->getColumn());
                                 stepStack.push_back(currentStepBound - 1);
                             }
                         }
@@ -211,16 +211,16 @@ namespace storm {
                     }
                     
                     for (typename storm::storage::SparseMatrix<T>::const_iterator entryIt = backwardTransitions.begin(currentState), entryIte = backwardTransitions.end(currentState); entryIt != entryIte; ++entryIt) {
-                        if (phiStates.get(entryIt->first) && (!statesWithProbabilityGreater0.get(entryIt->first) || (useStepBound && remainingSteps[entryIt->first] < currentStepBound - 1))) {
+                        if (phiStates.get(entryIt->getColumn()) && (!statesWithProbabilityGreater0.get(entryIt->getColumn()) || (useStepBound && remainingSteps[entryIt->getColumn()] < currentStepBound - 1))) {
                             // If we don't have a bound on the number of steps to take, just add the state to the stack.
                             if (!useStepBound) {
-                                statesWithProbabilityGreater0.set(entryIt->first, true);
-                                stack.push_back(entryIt->first);
+                                statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
+                                stack.push_back(entryIt->getColumn());
                             } else if (currentStepBound > 0) {
                                 // If there is at least one more step to go, we need to push the state and the new number of steps.
-                                remainingSteps[entryIt->first] = currentStepBound - 1;
-                                statesWithProbabilityGreater0.set(entryIt->first, true);
-                                stack.push_back(entryIt->first);
+                                remainingSteps[entryIt->getColumn()] = currentStepBound - 1;
+                                statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
+                                stack.push_back(entryIt->getColumn());
                                 stepStack.push_back(currentStepBound - 1);
                             }
                         }
@@ -290,13 +290,13 @@ namespace storm {
                         stack.pop_back();
                         
                         for (typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState), predecessorEntryIte = backwardTransitions.end(currentState); predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
-                            if (phiStates.get(predecessorEntryIt->first) && !nextStates.get(predecessorEntryIt->first)) {
+                            if (phiStates.get(predecessorEntryIt->getColumn()) && !nextStates.get(predecessorEntryIt->getColumn())) {
                                 // Check whether the predecessor has only successors in the current state set for one of the
                                 // nondeterminstic choices.
-                                for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->first]; row < nondeterministicChoiceIndices[predecessorEntryIt->first + 1]; ++row) {
+                                for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
                                     bool allSuccessorsInCurrentStates = true;
                                     for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) {
-                                        if (!currentStates.get(successorEntryIt->first)) {
+                                        if (!currentStates.get(successorEntryIt->getColumn())) {
                                             allSuccessorsInCurrentStates = false;
                                             break;
                                         }
@@ -306,8 +306,8 @@ namespace storm {
                                     // add it to the set of states for the next iteration and perform a backward search from
                                     // that state.
                                     if (allSuccessorsInCurrentStates) {
-                                        nextStates.set(predecessorEntryIt->first, true);
-                                        stack.push_back(predecessorEntryIt->first);
+                                        nextStates.set(predecessorEntryIt->getColumn(), true);
+                                        stack.push_back(predecessorEntryIt->getColumn());
                                         break;
                                     }
                                 }
@@ -401,14 +401,14 @@ namespace storm {
                     }
                     
                     for(typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState), predecessorEntryIte = backwardTransitions.end(currentState); predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
-                        if (phiStates.get(predecessorEntryIt->first) && (!statesWithProbabilityGreater0.get(predecessorEntryIt->first) || (useStepBound && remainingSteps[predecessorEntryIt->first] < currentStepBound - 1))) {
+                        if (phiStates.get(predecessorEntryIt->getColumn()) && (!statesWithProbabilityGreater0.get(predecessorEntryIt->getColumn()) || (useStepBound && remainingSteps[predecessorEntryIt->getColumn()] < currentStepBound - 1))) {
                             // Check whether the predecessor has at least one successor in the current state set for every
                             // nondeterministic choice.
                             bool addToStatesWithProbabilityGreater0 = true;
-                            for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->first]; row < nondeterministicChoiceIndices[predecessorEntryIt->first + 1]; ++row) {
+                            for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
                                 bool hasAtLeastOneSuccessorWithProbabilityGreater0 = false;
                                 for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) {
-                                    if (statesWithProbabilityGreater0.get(successorEntryIt->first)) {
+                                    if (statesWithProbabilityGreater0.get(successorEntryIt->getColumn())) {
                                         hasAtLeastOneSuccessorWithProbabilityGreater0 = true;
                                         break;
                                     }
@@ -424,13 +424,13 @@ namespace storm {
                             if (addToStatesWithProbabilityGreater0) {
                                 // If we don't have a bound on the number of steps to take, just add the state to the stack.
                                 if (!useStepBound) {
-                                    statesWithProbabilityGreater0.set(predecessorEntryIt->first, true);
-                                    stack.push_back(predecessorEntryIt->first);
+                                    statesWithProbabilityGreater0.set(predecessorEntryIt->getColumn(), true);
+                                    stack.push_back(predecessorEntryIt->getColumn());
                                 } else if (currentStepBound > 0) {
                                     // If there is at least one more step to go, we need to push the state and the new number of steps.
-                                    remainingSteps[predecessorEntryIt->first] = currentStepBound - 1;
-                                    statesWithProbabilityGreater0.set(predecessorEntryIt->first, true);
-                                    stack.push_back(predecessorEntryIt->first);
+                                    remainingSteps[predecessorEntryIt->getColumn()] = currentStepBound - 1;
+                                    statesWithProbabilityGreater0.set(predecessorEntryIt->getColumn(), true);
+                                    stack.push_back(predecessorEntryIt->getColumn());
                                     stepStack.push_back(currentStepBound - 1);
                                 }
                             }
@@ -501,12 +501,12 @@ namespace storm {
                         stack.pop_back();
                         
                         for(typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState), predecessorEntryIte = backwardTransitions.end(currentState); predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
-                            if (phiStates.get(predecessorEntryIt->first) && !nextStates.get(predecessorEntryIt->first)) {
+                            if (phiStates.get(predecessorEntryIt->getColumn()) && !nextStates.get(predecessorEntryIt->getColumn())) {
                                 // Check whether the predecessor has only successors in the current state set for all of the
                                 // nondeterminstic choices.
                                 bool allSuccessorsInCurrentStatesForAllChoices = true;
-                                for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(nondeterministicChoiceIndices[predecessorEntryIt->first]), successorEntryIte = transitionMatrix.begin(nondeterministicChoiceIndices[predecessorEntryIt->first + 1]); successorEntryIt != successorEntryIte; ++successorEntryIt) {
-                                    if (!currentStates.get(successorEntryIt->first)) {
+                                for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]), successorEntryIte = transitionMatrix.begin(nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]); successorEntryIt != successorEntryIte; ++successorEntryIt) {
+                                    if (!currentStates.get(successorEntryIt->getColumn())) {
                                         allSuccessorsInCurrentStatesForAllChoices = false;
                                         goto afterCheckLoop;
                                     }
@@ -517,8 +517,8 @@ namespace storm {
                                 // add it to the set of states for the next iteration and perform a backward search from
                                 // that state.
                                 if (allSuccessorsInCurrentStatesForAllChoices) {
-                                    nextStates.set(predecessorEntryIt->first, true);
-                                    stack.push_back(predecessorEntryIt->first);
+                                    nextStates.set(predecessorEntryIt->getColumn(), true);
+                                    stack.push_back(predecessorEntryIt->getColumn());
                                 }
                             }
                         }
diff --git a/src/utility/matrix.h b/src/utility/matrix.h
index 446fb413f..1027e7e42 100644
--- a/src/utility/matrix.h
+++ b/src/utility/matrix.h
@@ -32,7 +32,7 @@ namespace storm {
                         // If a valid choice for this state is defined, we copy over the corresponding entries.
                         typename storm::storage::SparseMatrix<T>::const_rows selectedRow = transitionMatrix.getRow(choice);
                         for (auto const& entry : selectedRow) {
-                            matrixBuilder.addNextValue(state, entry.first, entry.second);
+                            matrixBuilder.addNextValue(state, entry.getColumn(), entry.getValue());
                         }
                     } else {
                         // If no valid choice for the state is defined, we insert a self-loop.
diff --git a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
index 2b301a1e7..89c5c9c6e 100644
--- a/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/DeterministicSparseTransitionParserTest.cpp
@@ -35,68 +35,68 @@ TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
 
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.4, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.4, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.4, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.4, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(0.7, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(0.7, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(0.9, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(0.9, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(0.224653, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(0.224653, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(7, cIter->first);
-	ASSERT_EQ(0.775347, cIter->second);
+	ASSERT_EQ(7, cIter->getColumn());
+	ASSERT_EQ(0.775347, cIter->getValue());
 }
 
 TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
@@ -112,56 +112,56 @@ TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = rewardMatrix.begin(0);
 
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(10, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(10, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(5, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(5.5, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(5.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(21.4, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(21.4, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(4, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(4, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(2, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(1.1, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(1.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(9.5, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(9.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(6.7, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(6.7, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(12, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(12, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(35.224653, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(35.224653, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(7, cIter->first);
-	ASSERT_EQ(9.875347, cIter->second);
+	ASSERT_EQ(7, cIter->getColumn());
+	ASSERT_EQ(9.875347, cIter->getValue());
 }
 
 
@@ -201,17 +201,17 @@ TEST(DeterministicSparseTransitionParserTest, FixDeadlocks) {
 	ASSERT_EQ(23, transitionMatrix.getEntryCount());
 
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(7);
-	ASSERT_EQ(7, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(7, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(6, cIter->first);
-	ASSERT_EQ(0.224653, cIter->second);
+	ASSERT_EQ(6, cIter->getColumn());
+	ASSERT_EQ(0.224653, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(7, cIter->first);
-	ASSERT_EQ(0.775347, cIter->second);
+	ASSERT_EQ(7, cIter->getColumn());
+	ASSERT_EQ(0.775347, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(8, cIter->first);
-	ASSERT_EQ(0, cIter->second);
+	ASSERT_EQ(8, cIter->getColumn());
+	ASSERT_EQ(0, cIter->getValue());
 }
 
 TEST(DeterministicSparseTransitionParserTest, DontFixDeadlocks) {
diff --git a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
index 81c2ccfb8..38b152cd4 100644
--- a/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
+++ b/test/functional/parser/MarkovAutomatonSparseTransitionParserTest.cpp
@@ -79,29 +79,29 @@ TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
 	// Finally, test the transition matrix itself.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
 
-	ASSERT_EQ(2, cIter->second);
+	ASSERT_EQ(2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->second);
+	ASSERT_EQ(2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->second);
+	ASSERT_EQ(4, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(8, cIter->second);
+	ASSERT_EQ(8, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
 	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
@@ -157,29 +157,29 @@ TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
 	// Finally, test the transition matrix itself.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
 
-	ASSERT_EQ(2, cIter->second);
+	ASSERT_EQ(2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->second);
+	ASSERT_EQ(2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->second);
+	ASSERT_EQ(4, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(8, cIter->second);
+	ASSERT_EQ(8, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
 	ASSERT_EQ(transitionMatrix.end(), cIter);
 }
diff --git a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
index 21240a9dd..9494c983f 100644
--- a/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
+++ b/test/functional/parser/NondeterministicSparseTransitionParserTest.cpp
@@ -48,71 +48,71 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
 
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(0.9, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(0.9, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.9, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.9, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.5, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.5, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(0.001, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(0.001, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(0.999, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(0.999, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.7, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.7, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.3, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.3, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0.6, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0.6, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 }
 
 TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
@@ -128,56 +128,56 @@ TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing)
 	// Test every entry of the matrix.
 	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
 
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(30, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(30, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(15.2, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(15.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(75, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(75, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(2.45, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(2.45, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(0, cIter->first);
-	ASSERT_EQ(0.114, cIter->second);
+	ASSERT_EQ(0, cIter->getColumn());
+	ASSERT_EQ(0.114, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(90, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(90, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(55, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(55, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(87, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(87, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(2, cIter->first);
-	ASSERT_EQ(13, cIter->second);
+	ASSERT_EQ(2, cIter->getColumn());
+	ASSERT_EQ(13, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(3, cIter->first);
-	ASSERT_EQ(999, cIter->second);
+	ASSERT_EQ(3, cIter->getColumn());
+	ASSERT_EQ(999, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.7, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.7, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.3, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.3, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.1, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(6, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(6, cIter->getValue());
 }
 
 TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
@@ -224,26 +224,26 @@ TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
 
 	storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(8);
 
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.7, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.7, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.3, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.3, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(1, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(1, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(4, cIter->first);
-	ASSERT_EQ(0.2, cIter->second);
+	ASSERT_EQ(4, cIter->getColumn());
+	ASSERT_EQ(0.2, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(0.6, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(0.6, cIter->getValue());
 	cIter++;
-	ASSERT_EQ(5, cIter->first);
-	ASSERT_EQ(1, cIter->second);
+	ASSERT_EQ(5, cIter->getColumn());
+	ASSERT_EQ(1, cIter->getValue());
 
 }
 
diff --git a/test/functional/storage/SparseMatrixTest.cpp b/test/functional/storage/SparseMatrixTest.cpp
index 69517a6d4..de89f4950 100644
--- a/test/functional/storage/SparseMatrixTest.cpp
+++ b/test/functional/storage/SparseMatrixTest.cpp
@@ -147,7 +147,7 @@ TEST(SparseMatrix, Build) {
 }
 
 TEST(SparseMatrix, CreationWithMovingContents) {
-    std::vector<std::pair<uint_fast64_t, double>> columnsAndValues;
+    std::vector<storm::storage::MatrixEntry<double>> columnsAndValues;
     columnsAndValues.emplace_back(1, 1.0);
     columnsAndValues.emplace_back(2, 1.2);
     columnsAndValues.emplace_back(0, 0.5);
@@ -540,24 +540,24 @@ TEST(SparseMatrix, Iteration) {
     ASSERT_NO_THROW(matrix = matrixBuilder.build());
     
     for (auto const& entry : matrix.getRow(4)) {
-        if (entry.first == 0) {
-            ASSERT_EQ(0.1, entry.second);
-        } else if (entry.first == 1) {
-            ASSERT_EQ(0.2, entry.second);
-        } else if (entry.first == 3) {
-            ASSERT_EQ(0.3, entry.second);
+        if (entry.getColumn() == 0) {
+            ASSERT_EQ(0.1, entry.getValue());
+        } else if (entry.getColumn() == 1) {
+            ASSERT_EQ(0.2, entry.getValue());
+        } else if (entry.getColumn() == 3) {
+            ASSERT_EQ(0.3, entry.getValue());
         } else {
             ASSERT_TRUE(false);
         }
     }
     
     for (storm::storage::SparseMatrix<double>::iterator it = matrix.begin(4), ite = matrix.end(4); it != ite; ++it) {
-        if (it->first == 0) {
-            ASSERT_EQ(0.1, it->second);
-        } else if (it->first == 1) {
-            ASSERT_EQ(0.2, it->second);
-        } else if (it->first == 3) {
-            ASSERT_EQ(0.3, it->second);
+        if (it->getColumn() == 0) {
+            ASSERT_EQ(0.1, it->getValue());
+        } else if (it->getColumn() == 1) {
+            ASSERT_EQ(0.2, it->getValue());
+        } else if (it->getColumn() == 3) {
+            ASSERT_EQ(0.3, it->getValue());
         } else {
             ASSERT_TRUE(false);
         }
diff --git a/test/performance/storage/SparseMatrixTest.cpp b/test/performance/storage/SparseMatrixTest.cpp
index 367bd3401..b59d283af 100644
--- a/test/performance/storage/SparseMatrixTest.cpp
+++ b/test/performance/storage/SparseMatrixTest.cpp
@@ -15,7 +15,7 @@ TEST(SparseMatrix, Iteration) {
     for (uint_fast64_t row = 0; row < matrix.getRowCount(); ++row) {
         for (auto const& entry : matrix.getRow(row)) {
             // The following can never be true, but prevents the compiler from optimizing away the loop.
-            if (entry.first > matrix.getColumnCount()) {
+            if (entry.getColumn() > matrix.getColumnCount()) {
                 ASSERT_TRUE(false);
             }
         }

From 9d3e78ab898f1b862710f901a7391d4c0f40fec8 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 6 May 2014 23:24:04 +0200
Subject: [PATCH 110/147] Cudd now gets 2GB instead of 2MB by default.

Former-commit-id: 06cf8094930ec671fa92d260896bfe894a2d7c7b
---
 src/storage/dd/CuddDdManager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index b3854ee36..087382c71 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -32,7 +32,7 @@ bool CuddOptionsRegistered = storm::settings::Settings::registerNewModule([] (st
 namespace storm {
     namespace dd {
         DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
-            this->cuddManager.SetMaxMemory(storm::settings::Settings::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024);
+            this->cuddManager.SetMaxMemory(storm::settings::Settings::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024 * 1024);
             this->cuddManager.SetEpsilon(storm::settings::Settings::getInstance()->getOptionByLongName("cuddprec").getArgument(0).getValueAsDouble());
         }
         

From 3158d19123def9d2ba29374a9a8aadebcea5093f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 7 May 2014 18:27:44 +0200
Subject: [PATCH 111/147] Started working on adapting LP solver interface to
 new expressions.

Former-commit-id: 6131736a7fe0e9411a2cef385722d0619e63105c
---
 src/solver/GlpkLpSolver.cpp                   | 262 ++++++++++--------
 src/solver/GlpkLpSolver.h                     |  81 ++++--
 src/solver/GurobiLpSolver.h                   |  80 ++++--
 src/solver/LpSolver.h                         | 166 ++++++-----
 src/storage/expressions/Expression.cpp        |  10 +
 src/storage/expressions/Expression.h          |   8 +
 .../expressions/LinearityCheckVisitor.cpp     |  78 ++++++
 .../expressions/LinearityCheckVisitor.h       |  41 +++
 8 files changed, 493 insertions(+), 233 deletions(-)
 create mode 100644 src/storage/expressions/LinearityCheckVisitor.cpp
 create mode 100644 src/storage/expressions/LinearityCheckVisitor.h

diff --git a/src/solver/GlpkLpSolver.cpp b/src/solver/GlpkLpSolver.cpp
index e122fcb16..fc2c5f261 100644
--- a/src/solver/GlpkLpSolver.cpp
+++ b/src/solver/GlpkLpSolver.cpp
@@ -4,13 +4,10 @@
 
 #include <iostream>
 
-#include "src/exceptions/InvalidStateException.h"
 #include "src/settings/Settings.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-
-extern log4cplus::Logger logger;
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidAccessException.h"
+#include "src/exceptions/InvalidStateException.h"
 
 bool GlpkLpSolverOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
 	instance->addOption(storm::settings::OptionBuilder("GlpkLpSolver", "glpkoutput", "", "If set, the glpk output will be printed to the command line.").build());
@@ -22,7 +19,7 @@ bool GlpkLpSolverOptionsRegistered = storm::settings::Settings::registerNewModul
 
 namespace storm {
     namespace solver {
-        GlpkLpSolver::GlpkLpSolver(std::string const& name, ModelSense const& modelSense) : LpSolver(modelSense), lp(nullptr), nextVariableIndex(1), nextConstraintIndex(1), modelContainsIntegerVariables(false), isInfeasibleFlag(false), isUnboundedFlag(false), rowIndices(), columnIndices(), coefficientValues() {
+        GlpkLpSolver::GlpkLpSolver(std::string const& name, ModelSense const& modelSense) : LpSolver(modelSense), lp(nullptr), variableNameToIndexMap(), nextVariableIndex(0), nextConstraintIndex(0), modelContainsIntegerVariables(false), isInfeasibleFlag(false), isUnboundedFlag(false), rowIndices(), columnIndices(), coefficientValues() {
             // Create the LP problem for glpk.
             lp = glp_create_prob();
             
@@ -38,11 +35,11 @@ namespace storm {
             coefficientValues.push_back(0);
         }
         
-        GlpkLpSolver::GlpkLpSolver(std::string const& name) : GlpkLpSolver(name, MINIMIZE) {
+        GlpkLpSolver::GlpkLpSolver(std::string const& name) : GlpkLpSolver(name, ModelSense::MINIMIZE) {
             // Intentionally left empty.
         }
         
-        GlpkLpSolver::GlpkLpSolver() : GlpkLpSolver("", MINIMIZE) {
+        GlpkLpSolver::GlpkLpSolver() : GlpkLpSolver("", ModelSense::MINIMIZE) {
             // Intentionally left empty.
         }
         
@@ -56,69 +53,126 @@ namespace storm {
             glp_free_env();
         }
         
-        uint_fast64_t GlpkLpSolver::createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
+        void GlpkLpSolver::addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
             glp_add_cols(this->lp, 1);
             glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            switch (variableType) {
-                case LpSolver::BOUNDED:
-                    glp_set_col_bnds(lp, nextVariableIndex, GLP_DB, lowerBound, upperBound);
-                    break;
-                case LpSolver::UNBOUNDED:
-                    glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
-                    break;
-                case LpSolver::UPPER_BOUND:
-                    glp_set_col_bnds(lp, nextVariableIndex, GLP_UP, 0, upperBound);
-                    break;
-                case LpSolver::LOWER_BOUND:
-                    glp_set_col_bnds(lp, nextVariableIndex, GLP_LO, lowerBound, 0);
-                    break;
-            }
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_DB, lowerBound, upperBound);
             glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
             glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            ++nextVariableIndex;
-            
-            this->currentModelHasBeenOptimized = false;
-            return nextVariableIndex - 1;
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
         }
         
-        uint_fast64_t GlpkLpSolver::createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
-            uint_fast64_t index = this->createContinuousVariable(name, variableType, lowerBound, upperBound, objectiveFunctionCoefficient);
-            glp_set_col_kind(this->lp, index, GLP_IV);
+        void GlpkLpSolver::addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_LO, lowerBound, 0);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
+        }
+        
+        void GlpkLpSolver::addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_UP, 0, upperBound);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
+        }
+        
+        void GlpkLpSolver::addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
+        }
+        
+        void GlpkLpSolver::addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_DB, lowerBound, upperBound);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
             this->modelContainsIntegerVariables = true;
-            return index;
         }
         
-        uint_fast64_t GlpkLpSolver::createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) {
-            uint_fast64_t index = this->createContinuousVariable(name, UNBOUNDED, 0, 1, objectiveFunctionCoefficient);
-            glp_set_col_kind(this->lp, index, GLP_BV);
+        void GlpkLpSolver::addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_LO, lowerBound, 0);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
+            this->modelContainsIntegerVariables = true;
+        }
+
+        void GlpkLpSolver::addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_UP, 0, upperBound);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
+            this->modelContainsIntegerVariables = true;
+        }
+        
+        void GlpkLpSolver::addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
+            this->modelContainsIntegerVariables = true;
+        }
+        
+        void GlpkLpSolver::addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            glp_add_cols(this->lp, 1);
+            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
+            glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
+            glp_set_col_kind(this->lp, nextVariableIndex, GLP_BV);
+            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
+            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
+            ++this->nextVariableIndex;
             this->modelContainsIntegerVariables = true;
-            return index;
         }
         
         void GlpkLpSolver::update() const {
             // Intentionally left empty.
         }
         
-        void GlpkLpSolver::addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rightHandSideValue) {
-            if (variables.size() != coefficients.size()) {
-                LOG4CPLUS_ERROR(logger, "Sizes of variable indices vector and coefficients vector do not match.");
-                throw storm::exceptions::InvalidStateException() << "Sizes of variable indices vector and coefficients vector do not match.";
-            }
-
+        void GlpkLpSolver::addConstraint(std::string const& name, storm::expressions::Expression const& constraint) {
             // Add the row that will represent this constraint.
             glp_add_rows(this->lp, 1);
             glp_set_row_name(this->lp, nextConstraintIndex, name.c_str());
             
+            LOG_THROW(constraint.isRelationalExpression(), storm::exceptions::InvalidArgumentException, "Illegal constraint is not a relational expression.");
+            LOG_THROW(constraint.getOperator() != storm::expressions::OperatorType::NotEqual, storm::exceptions::InvalidArgumentException, "Illegal constraint uses inequality operator.");
+            
+            // TODO: get variable/coefficients vector from constraint.
+            
+            
             // Determine the type of the constraint and add it properly.
-            switch (boundType) {
-                case LESS:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightHandSideValue - storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
+            switch (constraint.getOperator()) {
+                case storm::expressions::OperatorType::Less:
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightHandSideValue - storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble());
                     break;
                 case LESS_EQUAL:
                     glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightHandSideValue);
                     break;
                 case GREATER:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightHandSideValue + storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble(), 0);
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightHandSideValue + storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), 0);
                     break;
                 case GREATER_EQUAL:
                     glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightHandSideValue, 0);
@@ -143,13 +197,13 @@ namespace storm {
             this->isUnboundedFlag = false;
             
             // Start by setting the model sense.
-            glp_set_obj_dir(this->lp, this->getModelSense() == MINIMIZE ? GLP_MIN : GLP_MAX);
+            glp_set_obj_dir(this->lp, this->getModelSense() == LpSolver::ModelSense::MINIMIZE ? GLP_MIN : GLP_MAX);
             
             glp_load_matrix(this->lp, rowIndices.size() - 1, rowIndices.data(), columnIndices.data(), coefficientValues.data());
             
             int error = 0;
             if (this->modelContainsIntegerVariables) {
-                glp_iocp* parameters = new glp_iocp;
+                glp_iocp* parameters = new glp_iocp();
                 glp_init_iocp(parameters);
                 parameters->presolve = GLP_ON;
                 parameters->tol_int = storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble();
@@ -171,11 +225,7 @@ namespace storm {
                 error = glp_simplex(this->lp, nullptr);
             }
             
-            if (error != 0) {
-                LOG4CPLUS_ERROR(logger, "Unable to optimize glpk model (" << error << ").");
-                throw storm::exceptions::InvalidStateException() << "Unable to optimize glpk model (" << error << ").";
-            }
-            
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to optimize glpk model (" << error << ").");
             this->currentModelHasBeenOptimized = true;
         }
         
@@ -217,103 +267,75 @@ namespace storm {
             return status == GLP_OPT;
         }
         
-        int_fast64_t GlpkLpSolver::getIntegerValue(uint_fast64_t variableIndex) const {
+        double GlpkLpSolver::getContinuousValue(std::string const& name) const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from infeasible model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model.";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unbounded model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model.";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unoptimized model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model.";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get glpk solution from infeasible model.");
+                LOG_THROW(!this->isUnbounded(),  storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unbounded model.");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unoptimized model.");
             }
-           
+            
+            auto variableIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(variableIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidAccessException, "Accessing value of unknown variable '" << name << "'.");
+            
             double value = 0;
             if (this->modelContainsIntegerVariables) {
-                value = glp_mip_col_val(this->lp, static_cast<int>(variableIndex));
+                value = glp_mip_col_val(this->lp, static_cast<int>(variableIndexPair->second));
             } else {
-                value = glp_get_col_prim(this->lp, static_cast<int>(variableIndex));
-            }
-
-            if (std::abs(value - static_cast<int>(value)) <= storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) {
-                // Nothing to do in this case.
-            } else if (std::abs(value) > storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) {
-                LOG4CPLUS_ERROR(logger, "Illegal value for integer variable in glpk solution (" << value << ").");
-                throw storm::exceptions::InvalidStateException() << "Illegal value for integer variable in glpk solution (" << value << ").";
+                value = glp_get_col_prim(this->lp, static_cast<int>(variableIndexPair->second));
             }
-            
-            return static_cast<int_fast64_t>(value);
+            return value;
         }
         
-        bool GlpkLpSolver::getBinaryValue(uint_fast64_t variableIndex) const {
+        int_fast64_t GlpkLpSolver::getIntegerValue(std::string const& name) const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from infeasible model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model.";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unbounded model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model.";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unoptimized model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model.";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get glpk solution from infeasible model.");
+                LOG_THROW(!this->isUnbounded(),  storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unbounded model.");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unoptimized model.");
             }
+           
+            auto variableIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(variableIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidAccessException, "Accessing value of unknown variable '" << name << "'.");
 
             double value = 0;
             if (this->modelContainsIntegerVariables) {
-                value = glp_mip_col_val(this->lp, static_cast<int>(variableIndex));
+                value = glp_mip_col_val(this->lp, static_cast<int>(variableIndexPair->second));
             } else {
-                value = glp_get_col_prim(this->lp, static_cast<int>(variableIndex));
+                value = glp_get_col_prim(this->lp, static_cast<int>(variableIndexPair->second));
             }
 
-            if (std::abs(value - 1) <= storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) {
-                // Nothing to do in this case.
-            } else if (std::abs(value) > storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) {
-                LOG4CPLUS_ERROR(logger, "Illegal value for binary variable in Gurobi solution (" << value << ").");
-                throw storm::exceptions::InvalidStateException() << "Illegal value for binary variable in Gurobi solution (" << value << ").";
-            }
+            // Now check the desired precision was actually achieved.
+            LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for integer variable in glpk solution (" << value << ").");
             
-            return static_cast<bool>(value);
+            return static_cast<int_fast64_t>(value);
         }
         
-        double GlpkLpSolver::getContinuousValue(uint_fast64_t variableIndex) const {
+        bool GlpkLpSolver::getBinaryValue(std::string const& name) const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from infeasible model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model.";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unbounded model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model.";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unoptimized model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model.";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get glpk solution from infeasible model.");
+                LOG_THROW(!this->isUnbounded(),  storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unbounded model.");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unoptimized model.");
             }
 
+            auto variableIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(variableIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidAccessException, "Accessing value of unknown variable '" << name << "'.");
+            
             double value = 0;
             if (this->modelContainsIntegerVariables) {
-                value = glp_mip_col_val(this->lp, static_cast<int>(variableIndex));
+                value = glp_mip_col_val(this->lp, static_cast<int>(variableIndexPair->second));
             } else {
-                value = glp_get_col_prim(this->lp, static_cast<int>(variableIndex));
+                value = glp_get_col_prim(this->lp, static_cast<int>(variableIndexPair->second));
             }
-            return value;
+
+            LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for binary variable in glpk solution (" << value << ").");
+            
+            return static_cast<bool>(value);
         }
         
         double GlpkLpSolver::getObjectiveValue() const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from infeasible model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model.";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unbounded model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model.";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get glpk solution from unoptimized model.");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model.";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get glpk solution from infeasible model.");
+                LOG_THROW(!this->isUnbounded(),  storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unbounded model.");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get glpk solution from unoptimized model.");
             }
 
             double value = 0;
diff --git a/src/solver/GlpkLpSolver.h b/src/solver/GlpkLpSolver.h
index 2bc2bf397..0045ced73 100644
--- a/src/solver/GlpkLpSolver.h
+++ b/src/solver/GlpkLpSolver.h
@@ -14,7 +14,6 @@
 namespace storm {
     namespace solver {
 #ifdef STORM_HAVE_GLPK
-        
         /*!
          * A class that implements the LpSolver interface using glpk as the background solver.
          */
@@ -56,33 +55,53 @@ namespace storm {
              */
             virtual ~GlpkLpSolver();
             
-            virtual uint_fast64_t createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override;
-            virtual uint_fast64_t createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override;
-            virtual uint_fast64_t createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override;
+            // Methods to add continuous variables.
+            virtual void addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
+            
+            // Methods to add integer variables.
+            virtual void addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
+
+            // Methods to add binary variables.
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override;
+
+            // Methods to incorporate recent changes.
             virtual void update() const override;
             
-            virtual void addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rightHandSideValue) override;
+            // Methods to add constraints
+            virtual void addConstraint(std::string const& name, storm::expressions::Expression const& constraint) override;
             
+            // Methods to optimize and retrieve optimality status.
             virtual void optimize() const override;
             virtual bool isInfeasible() const override;
             virtual bool isUnbounded() const override;
             virtual bool isOptimal() const override;
 
-            virtual int_fast64_t getIntegerValue(uint_fast64_t variableIndex) const override;
-            virtual bool getBinaryValue(uint_fast64_t variableIndex) const override;
-            virtual double getContinuousValue(uint_fast64_t variableIndex) const override;
+            // Methods to retrieve values of variables and the objective function in the optimal solutions.
+            virtual double getContinuousValue(std::string const& name) const override;
+            virtual int_fast64_t getIntegerValue(std::string const& name) const override;
+            virtual bool getBinaryValue(std::string const& name) const override;
             virtual double getObjectiveValue() const override;
 
+            // Methods to print the LP problem to a file.
             virtual void writeModelToFile(std::string const& filename) const override;
             
         private:
             // The glpk LP problem.
             glp_prob* lp;
             
-            // A counter that keeps track of the next free variable index.
+            // A mapping from variable names to their indices.
+            std::map<std::string, uint_fast64_t> variableNameToIndexMap;
+            
+            // A counter used for getting the next variable index.
             uint_fast64_t nextVariableIndex;
             
-            // A counter that keeps track of the next free constraint index.
+            // A counter used for getting the next constraint index.
             uint_fast64_t nextConstraintIndex;
             
             // A flag storing whether the model is an LP or an MILP.
@@ -121,15 +140,39 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual uint_fast64_t createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override {
+            virtual void addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
+            }
+            
+            virtual void addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
+            }
+            
+            virtual void addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
+            }
+            
+            virtual void addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual uint_fast64_t createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override {
+            virtual void addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual uint_fast64_t createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override {
+            virtual void addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
+            }
+            
+            virtual void addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
+            }
+            
+            virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
+            }
+            
+            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
@@ -137,14 +180,14 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual void addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rightHandSideValue) override {
+            virtual void addConstraint(std::string const& name, storm::expressions::Expression const& constraint) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
-                        
+            
             virtual void optimize() const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
-
+            
             virtual bool isInfeasible() const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
@@ -157,15 +200,15 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual int_fast64_t getIntegerValue(uint_fast64_t variableIndex) const override {
+            virtual double getContinuousValue(std::string const& name) const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual bool getBinaryValue(uint_fast64_t variableIndex) const override {
+            virtual int_fast64_t getIntegerValue(std::string const& name) const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual double getContinuousValue(uint_fast64_t variableIndex) const override {
+            virtual bool getBinaryValue(std::string const& name) const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
diff --git a/src/solver/GurobiLpSolver.h b/src/solver/GurobiLpSolver.h
index 18c5bbdbd..27ac66c52 100644
--- a/src/solver/GurobiLpSolver.h
+++ b/src/solver/GurobiLpSolver.h
@@ -60,23 +60,40 @@ namespace storm {
              */
             virtual ~GurobiLpSolver();
             
-            virtual uint_fast64_t createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override;
-            virtual uint_fast64_t createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override;
-            virtual uint_fast64_t createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override;
+            // Methods to add continuous variables.
+            virtual void addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
+            
+            // Methods to add integer variables.
+            virtual void addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override;
+            virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
+            
+            // Methods to add binary variables.
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override;
+            
+            // Methods to incorporate recent changes.
             virtual void update() const override;
-
-            virtual void addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rightHandSideValue) override;
             
+            // Methods to add constraints
+            virtual void addConstraint(std::string const& name, storm::expressions::Expression const& constraint) override;
+            
+            // Methods to optimize and retrieve optimality status.
             virtual void optimize() const override;
             virtual bool isInfeasible() const override;
             virtual bool isUnbounded() const override;
             virtual bool isOptimal() const override;
-
-            virtual int_fast64_t getIntegerValue(uint_fast64_t variableIndex) const override;
-            virtual bool getBinaryValue(uint_fast64_t variableIndex) const override;
-            virtual double getContinuousValue(uint_fast64_t variableIndex) const override;
+            
+            // Methods to retrieve values of variables and the objective function in the optimal solutions.
+            virtual double getContinuousValue(std::string const& name) const override;
+            virtual int_fast64_t getIntegerValue(std::string const& name) const override;
+            virtual bool getBinaryValue(std::string const& name) const override;
             virtual double getObjectiveValue() const override;
-
+            
+            // Methods to print the LP problem to a file.
             virtual void writeModelToFile(std::string const& filename) const override;
             
         private:
@@ -91,8 +108,8 @@ namespace storm {
             // The Gurobi model.
             GRBmodel* model;
             
-            // A counter that keeps track of the next free variable index.
-            uint_fast64_t nextVariableIndex;
+            // A mapping from variable names to their indices.
+            std::map<std::string, uint_fast64_t> variableNameToIndexMap;
         };
 #else
         // If Gurobi is not available, we provide a stub implementation that emits an error if any of its methods is called.
@@ -114,27 +131,46 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual uint_fast64_t createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override {
+            virtual void addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual uint_fast64_t createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) override {
+            virtual void addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";            }
+            
+            virtual void addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual uint_fast64_t createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override {
+            virtual void addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual void update() const override {
+            virtual void addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
+            }
+            
+            virtual void addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual void addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rightHandSideValue) override {
+            virtual void addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual void setModelSense(ModelSense const& modelSense) {
+            virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
+            }
+            
+            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
+            }
+            
+            virtual void update() const override {
+                throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
+            }
+            
+            virtual void addConstraint(std::string const& name, storm::expressions::Expression const& constraint) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
@@ -154,15 +190,15 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual int_fast64_t getIntegerValue(uint_fast64_t variableIndex) const override {
+            virtual double getContinuousValue(std::string const& name) const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual bool getBinaryValue(uint_fast64_t variableIndex) const override {
+            virtual int_fast64_t getIntegerValue(std::string const& name) const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual double getContinuousValue(uint_fast64_t variableIndex) const override {
+            virtual bool getBinaryValue(std::string const& name) const override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
@@ -175,7 +211,7 @@ namespace storm {
             }
         };
 #endif
-    
+
     }
 }
 
diff --git a/src/solver/LpSolver.h b/src/solver/LpSolver.h
index 311ee4b44..f775f2829 100644
--- a/src/solver/LpSolver.h
+++ b/src/solver/LpSolver.h
@@ -5,34 +5,17 @@
 #include <vector>
 #include <cstdint>
 
+#include "src/storage/expressions/Expression.h"
+
 namespace storm {
     namespace solver {
-
         /*!
          * An interface that captures the functionality of an LP solver.
          */
         class LpSolver {
         public:
-            // An enumeration to represent the possible types of variables. Variables may be either unbounded, have only
-            // a lower or an upper bound, respectively, or be bounded from below and from above.
-            enum VariableType {
-                UNBOUNDED,
-                LOWER_BOUND,
-                UPPER_BOUND,
-                BOUNDED,
-            };
-            
-            // An enumeration to represent the possible types of constraints.
-            enum BoundType {
-                LESS,
-                LESS_EQUAL,
-                GREATER,
-                GREATER_EQUAL,
-                EQUAL
-            };
-            
             // An enumeration to represent whether the objective function is to be minimized or maximized.
-            enum ModelSense {
+            enum class ModelSense {
                 MINIMIZE,
                 MAXIMIZE
             };
@@ -40,7 +23,7 @@ namespace storm {
             /*!
              * Creates an empty LP solver. By default the objective function is assumed to be minimized.
              */
-            LpSolver() : currentModelHasBeenOptimized(false), modelSense(MINIMIZE) {
+            LpSolver() : currentModelHasBeenOptimized(false), modelSense(ModelSense::MINIMIZE) {
                 // Intentionally left empty.
             }
             
@@ -55,52 +38,99 @@ namespace storm {
             }
 
             /*!
-             * Creates a continuous variable, i.e. a variable that may take all real values within its bounds.
+             * Registers an upper- and lower-bounded continuous variable, i.e. a variable that may take all real values
+             * within its bounds.
+             *
+             * @param name The name of the variable.
+             * @param lowerBound The lower bound of the variable.
+             * @param upperBound The upper bound of the variable.
+             * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
+             */
+            virtual void addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) = 0;
+            
+            /*!
+             * Registers a lower-bounded continuous variable, i.e. a variable that may take all real values up to its
+             * lower bound.
+             *
+             * @param name The name of the variable.
+             * @param lowerBound The lower bound of the variable.
+             * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
+             */
+            virtual void addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) = 0;
+
+            /*!
+             * Registers an upper-bounded continuous variable, i.e. a variable that may take all real values up to its
+             * upper bound.
+             *
+             * @param name The name of the variable.
+             * @param upperBound The upper bound of the variable.
+             * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
+             */
+            virtual void addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) = 0;
+            
+            /*!
+             * Registers a unbounded continuous variable, i.e. a variable that may take all real values.
              *
              * @param name The name of the variable.
-             * @param variableType The type of the variable.
-             * @param lowerBound The lower bound of the variable. Note that this parameter is ignored if the variable 
-             * is not bounded from below.
-             * @param upperBound The upper bound of the variable. Note that this parameter is ignored if the variable
-             * is not bounded from above.
              * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
-             * function. If set to zero, the variable is irrelevant for the objective value.
-             * @return The index of the newly created variable. This index can be used to retrieve the variables value
-             * in a solution after the model has been optimized.
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
              */
-            virtual uint_fast64_t createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) = 0;
+            virtual void addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient = 0) = 0;
             
             /*!
-             * Creates an integer variable.
+             * Registers an upper- and lower-bounded integer variable, i.e. a variable that may take all integer values
+             * within its bounds.
+             *
+             * @param name The name of the variable.
+             * @param lowerBound The lower bound of the variable.
+             * @param upperBound The upper bound of the variable.
+             * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
+             */
+            virtual void addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient = 0) = 0;
+            
+            /*!
+             * Registers a lower-bounded integer variable, i.e. a variable that may take all integer values up to its
+             * lower bound.
+             *
+             * @param name The name of the variable.
+             * @param lowerBound The lower bound of the variable.
+             * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
+             */
+            virtual void addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient = 0) = 0;
+            
+            /*!
+             * Registers an upper-bounded integer variable, i.e. a variable that may take all integer values up to its
+             * lower bound.
+             *
+             * @param name The name of the variable.
+             * @param upperBound The upper bound of the variable.
+             * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
+             */
+            virtual void addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient = 0) = 0;
+
+            /*!
+             * Registers an unbounded integer variable, i.e. a variable that may take all integer values.
              *
              * @param name The name of the variable.
-             * @param variableType The type of the variable.
-             * @param lowerBound The lower bound of the variable. Note that this parameter is ignored if the variable
-             * is not bounded from below.
-             * @param upperBound The upper bound of the variable. Note that this parameter is ignored if the variable
-             * is not bounded from above.
              * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
-             * function. If set to zero, the variable is irrelevant for the objective value.
-             * @return The index of the newly created variable. This index can be used to retrieve the variables value
-             * in a solution after the model has been optimized.
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
              */
-            virtual uint_fast64_t createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) = 0;
+            virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) = 0;
             
             /*!
-             * Creates a binary variable, i.e. a variable that may be either zero or one.
+             * Registers a boolean variable, i.e. a variable that may be either 0 or 1.
              *
              * @param name The name of the variable.
-             * @param variableType The type of the variable.
-             * @param lowerBound The lower bound of the variable. Note that this parameter is ignored if the variable
-             * is not bounded from below.
-             * @param upperBound The upper bound of the variable. Note that this parameter is ignored if the variable
-             * is not bounded from above.
              * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
-             * function. If set to zero, the variable is irrelevant for the objective value.
-             * @return The index of the newly created variable. This index can be used to retrieve the variables value
-             * in a solution after the model has been optimized.
+             * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
              */
-            virtual uint_fast64_t createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) = 0;
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) = 0;
             
             /*!
              * Updates the model to make the variables that have been declared since the last call to <code>update</code>
@@ -109,18 +139,13 @@ namespace storm {
             virtual void update() const = 0;
             
             /*!
-             * Adds a constraint of the form
-             *      a_1*x_1 + ... + a_n*x_n  op  c
-             * to the LP problem.
+             * Adds a the given constraint to the LP problem.
              *
              * @param name The name of the constraint. If empty, the constraint has no name.
-             * @param variables A vector of variable indices that define the appearing variables x_1, ..., x_n.
-             * @param coefficients A vector of coefficients that define the a_1, ..., a_n. The i-ith entry specifies the
-             * coefficient of the variable whose index appears at the i-th position in the vector of variable indices.
-             * @param boundType The bound type specifies the operator op used in the constraint.
-             * @param rhs This defines the value of the constant appearing on the right-hand side of the constraint.
+             * @param constraint An expression that represents the constraint. The given constraint must be a linear
+             * (in)equality over the registered variables.
              */
-            virtual void addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rhs) = 0;
+            virtual void addConstraint(std::string const& name, storm::expressions::Expression const& constraint) = 0;
             
             /*!
              * Optimizes the LP problem previously constructed. Afterwards, the methods isInfeasible, isUnbounded and
@@ -154,34 +179,31 @@ namespace storm {
             virtual bool isOptimal() const = 0;
             
             /*!
-             * Retrieves the value of the integer variable with the given index. Note that this may only be called, if
+             * Retrieves the value of the integer variable with the given name. Note that this may only be called, if
              * the model was found to be optimal, i.e. iff isOptimal() returns true.
              *
-             * @param variableIndex The index of the integer variable whose value to query. If this index does not
-             * belong to a previously declared integer variable, the behaviour is undefined.
+             * @param name The name of the variable whose integer value (in the optimal solution) to retrieve.
              * @return The value of the integer variable in the optimal solution.
              */
-            virtual int_fast64_t getIntegerValue(uint_fast64_t variableIndex) const = 0;
+            virtual int_fast64_t getIntegerValue(std::string const& name) const = 0;
             
             /*!
-             * Retrieves the value of the binary variable with the given index. Note that this may only be called, if
+             * Retrieves the value of the binary variable with the given name. Note that this may only be called, if
              * the model was found to be optimal, i.e. iff isOptimal() returns true.
              *
-             * @param variableIndex The index of the binary variable whose value to query. If this index does not
-             * belong to a previously declared binary variable, the behaviour is undefined.
+             * @param name The name of the variable whose binary (boolean) value (in the optimal solution) to retrieve.
              * @return The value of the binary variable in the optimal solution.
              */
-            virtual bool getBinaryValue(uint_fast64_t variableIndex) const = 0;
+            virtual bool getBinaryValue(std::string const& name) const = 0;
             
             /*!
-             * Retrieves the value of the continuous variable with the given index. Note that this may only be called,
+             * Retrieves the value of the continuous variable with the given name. Note that this may only be called,
              * if the model was found to be optimal, i.e. iff isOptimal() returns true.
              *
-             * @param variableIndex The index of the continuous variable whose value to query. If this index does not
-             * belong to a previously declared continuous variable, the behaviour is undefined.
+             * @param name The name of the variable whose continuous value (in the optimal solution) to retrieve.
              * @return The value of the continuous variable in the optimal solution.
              */
-            virtual double getContinuousValue(uint_fast64_t variableIndex) const = 0;
+            virtual double getContinuousValue(std::string const& name) const = 0;
 
             /*!
              * Retrieves the value of the objective function. Note that this may only be called, if the model was found
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index e30b53927..169578c34 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -95,6 +95,16 @@ namespace storm {
             return this->getBaseExpression().isFalse();
         }
         
+        bool Expression::isRelationalExpression() const {
+            if (!this->isFunctionApplication()) {
+                return false;
+            }
+            
+            return this->getOperator() == OperatorType::Equal || this->getOperator() == OperatorType::NotEqual
+            || this->getOperator() == OperatorType::Less || this->getOperator() == OperatorType::LessOrEqual
+            || this->getOperator() == OperatorType::Greater || this->getOperator() == OperatorType::GreaterOrEqual;
+        }
+        
         std::set<std::string> Expression::getVariables() const {
             return this->getBaseExpression().getVariables();
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 0c55408dc..81ae5cf54 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -230,6 +230,14 @@ namespace storm {
              */
             bool isFalse() const;
             
+            /*!
+             * Retrieves whether this expression is a relation expression, i.e., an expression that has a relation
+             * (equal, not equal, less, less or equal, etc.) as its top-level operator.
+             *
+             * @return True iff the expression is a relation expression.
+             */
+            bool isRelationalExpression() const;
+            
             /*!
              * Retrieves the set of all variables that appear in the expression.
              *
diff --git a/src/storage/expressions/LinearityCheckVisitor.cpp b/src/storage/expressions/LinearityCheckVisitor.cpp
new file mode 100644
index 000000000..d4086abf1
--- /dev/null
+++ b/src/storage/expressions/LinearityCheckVisitor.cpp
@@ -0,0 +1,78 @@
+#include "src/storage/expressions/LinearityCheckVisitor.h"
+#include "src/storage/expressions/Expressions.h"
+
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidTypeException.h"
+
+namespace storm {
+    namespace expressions {
+        bool LinearityCheckVisitor::check(BaseExpression const* expression) {
+            expression->accept(this);
+            return resultStack.top();
+        }
+        
+        void LinearityCheckVisitor::visit(IfThenElseExpression const* expression) {
+            // An if-then-else expression is never linear.
+            resultStack.push(false);
+        }
+        
+        void LinearityCheckVisitor::visit(BinaryBooleanFunctionExpression const* expression) {
+            // Boolean function applications are not allowed in linear expressions.
+            resultStack.push(false);
+        }
+        
+        void LinearityCheckVisitor::visit(BinaryNumericalFunctionExpression const* expression) {
+            bool leftResult = true;
+            bool rightResult = true;
+            switch (expression->getOperatorType()) {
+                case BinaryNumericalFunctionExpression::OperatorType::Plus:
+                case BinaryNumericalFunctionExpression::OperatorType::Minus:
+                    expression->getFirstOperand()->accept(this);
+                    leftResult = resultStack.top();
+                    
+                    if (!leftResult) {
+                        
+                    } else {
+                        resultStack.pop();
+
+                        expression->getSecondOperand()->accept(this);
+                    }
+
+                case BinaryNumericalFunctionExpression::OperatorType::Times:
+                case BinaryNumericalFunctionExpression::OperatorType::Divide:
+                case BinaryNumericalFunctionExpression::OperatorType::Min: resultStack.push(false); break;
+                case BinaryNumericalFunctionExpression::OperatorType::Max: resultStack.push(false); break;
+            }
+        }
+        
+        void LinearityCheckVisitor::visit(BinaryRelationExpression const* expression) {
+            resultStack.push(false);
+        }
+        
+        void LinearityCheckVisitor::visit(VariableExpression const* expression) {
+            resultStack.push(true);
+        }
+        
+        void LinearityCheckVisitor::visit(UnaryBooleanFunctionExpression const* expression) {
+            // Boolean function applications are not allowed in linear expressions.
+            resultStack.push(false);
+        }
+        
+        void LinearityCheckVisitor::visit(UnaryNumericalFunctionExpression const* expression) {
+            // Intentionally left empty (just pass subresult one level further).
+        }
+        
+        void LinearityCheckVisitor::visit(BooleanLiteralExpression const* expression) {
+            // Boolean function applications are not allowed in linear expressions.
+            resultStack.push(false);
+        }
+        
+        void LinearityCheckVisitor::visit(IntegerLiteralExpression const* expression) {
+            resultStack.push(true);
+        }
+        
+        void LinearityCheckVisitor::visit(DoubleLiteralExpression const* expression) {
+            resultStack.push(true);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/LinearityCheckVisitor.h b/src/storage/expressions/LinearityCheckVisitor.h
new file mode 100644
index 000000000..2b1c3937c
--- /dev/null
+++ b/src/storage/expressions/LinearityCheckVisitor.h
@@ -0,0 +1,41 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_LINEARITYCHECKVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_LINEARITYCHECKVISITOR_H_
+
+#include <stack>
+
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+
+namespace storm {
+    namespace expressions {
+        class LinearityCheckVisitor : public ExpressionVisitor {
+        public:
+            /*!
+             * Creates a linearity check visitor.
+             */
+            LinearityCheckVisitor() = default;
+            
+            /*!
+             * Checks that the given expression is linear.
+             */
+            bool check(BaseExpression const* expression);
+            
+            virtual void visit(IfThenElseExpression const* expression) override;
+            virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BinaryRelationExpression const* expression) override;
+            virtual void visit(VariableExpression const* expression) override;
+            virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BooleanLiteralExpression const* expression) override;
+            virtual void visit(IntegerLiteralExpression const* expression) override;
+            virtual void visit(DoubleLiteralExpression const* expression) override;
+            
+        private:
+            // A stack for communicating the results of the subexpressions.
+            std::stack<bool> resultStack;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_LINEARITYCHECKVISITOR_H_ */
\ No newline at end of file

From 024b98978f8e2c704a416b7cd0c66fe9426a1f7c Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 9 May 2014 19:01:36 +0200
Subject: [PATCH 112/147] Made internal changes to SimpleValuations to
 (hopefully) make it nice and fast.

Former-commit-id: 1e9f18f522a78f158cedf06b5532da5cdbac0c3f
---
 src/storage/dd/CuddDdForwardIterator.cpp    |  5 ++
 src/storage/dd/CuddDdForwardIterator.h      |  2 +-
 src/storage/expressions/SimpleValuation.cpp | 98 ++++++---------------
 src/storage/expressions/SimpleValuation.h   | 28 +-----
 4 files changed, 38 insertions(+), 95 deletions(-)

diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp
index c0e754c8b..017845b47 100644
--- a/src/storage/dd/CuddDdForwardIterator.cpp
+++ b/src/storage/dd/CuddDdForwardIterator.cpp
@@ -5,6 +5,10 @@
 
 namespace storm {
     namespace dd {
+        DdForwardIterator<DdType::CUDD>::DdForwardIterator() : ddManager(), generator(), cube(), value(), isAtEnd(), metaVariables(), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
+            // Intentionally left empty.
+        }
+        
         DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<std::string> const* metaVariables) : ddManager(ddManager), generator(generator), cube(cube), value(value), isAtEnd(isAtEnd), metaVariables(metaVariables), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
             // If the given generator is not yet at its end, we need to create the current valuation from the cube from
             // scratch.
@@ -49,6 +53,7 @@ namespace storm {
         }
         
         DdForwardIterator<DdType::CUDD>::~DdForwardIterator() {
+            // We free the pointers sind Cudd allocates them using malloc rather than new/delete.
             if (this->cube != nullptr) {
                 free(this->cube);
             }
diff --git a/src/storage/dd/CuddDdForwardIterator.h b/src/storage/dd/CuddDdForwardIterator.h
index 054438d2e..0515475a4 100644
--- a/src/storage/dd/CuddDdForwardIterator.h
+++ b/src/storage/dd/CuddDdForwardIterator.h
@@ -25,7 +25,7 @@ namespace storm {
             friend class Dd<DdType::CUDD>;
 
             // Default-instantiate the constructor.
-            DdForwardIterator() = default;
+            DdForwardIterator();
             
             // Forbid copy-construction and copy assignment, because ownership of the internal pointer is unclear then.
             DdForwardIterator(DdForwardIterator<DdType::CUDD> const& other) = delete;
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index d29e6a7c8..f930f7e10 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -2,102 +2,74 @@
 #include "src/storage/expressions/SimpleValuation.h"
 #include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/InvalidArgumentException.h"
+#include "src/exceptions/InvalidAccessException.h"
 
 namespace storm {
     namespace expressions {
-        SimpleValuation::SimpleValuation() : booleanIdentifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>()), integerIdentifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>()), doubleIdentifierToIndexMap(new std::unordered_map<std::string, uint_fast64_t>()), booleanValues(), integerValues(), doubleValues() {
-            // Intentionally left empty.
-        }
-        
         bool SimpleValuation::operator==(SimpleValuation const& other) const {
-            return this->booleanIdentifierToIndexMap.get() == other.booleanIdentifierToIndexMap.get() && this->integerIdentifierToIndexMap.get() == other.integerIdentifierToIndexMap.get() && this->doubleIdentifierToIndexMap.get() == other.doubleIdentifierToIndexMap.get() && this->booleanValues == other.booleanValues && this->integerValues == other.integerValues && this->doubleValues == other.doubleValues;
+            return this->identifierToValueMap == other.identifierToValueMap;
         }
         
         void SimpleValuation::addBooleanIdentifier(std::string const& name, bool initialValue) {
-            LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Boolean identifier '" << name << "' already registered.");
-            
-            this->booleanIdentifierToIndexMap->emplace(name, this->booleanValues.size());
-            this->booleanValues.push_back(initialValue);
+            LOG_THROW(this->identifierToValueMap.find(name) == this->identifierToValueMap.end(), storm::exceptions::InvalidArgumentException, "Identifier '" << name << "' already registered.");
+            this->identifierToValueMap.emplace(name, initialValue);
         }
         
         void SimpleValuation::addIntegerIdentifier(std::string const& name, int_fast64_t initialValue) {
-            LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Integer identifier '" << name << "' already registered.");
-
-            this->integerIdentifierToIndexMap->emplace(name, this->integerValues.size());
-            this->integerValues.push_back(initialValue);
+            LOG_THROW(this->identifierToValueMap.find(name) == this->identifierToValueMap.end(), storm::exceptions::InvalidArgumentException, "Identifier '" << name << "' already registered.");
+            this->identifierToValueMap.emplace(name, initialValue);
         }
         
         void SimpleValuation::addDoubleIdentifier(std::string const& name, double initialValue) {
-            LOG_THROW(this->booleanIdentifierToIndexMap->find(name) == this->booleanIdentifierToIndexMap->end(), storm::exceptions::InvalidArgumentException, "Double identifier '" << name << "' already registered.");
-
-            this->doubleIdentifierToIndexMap->emplace(name, this->doubleValues.size());
-            this->doubleValues.push_back(initialValue);
+            LOG_THROW(this->identifierToValueMap.find(name) == this->identifierToValueMap.end(), storm::exceptions::InvalidArgumentException, "Identifier '" << name << "' already registered.");
+            this->identifierToValueMap.emplace(name, initialValue);
         }
         
         void SimpleValuation::setBooleanValue(std::string const& name, bool value) {
-            this->booleanValues[this->booleanIdentifierToIndexMap->at(name)] = value;
+            this->identifierToValueMap[name] = value;
         }
         
         void SimpleValuation::setIntegerValue(std::string const& name, int_fast64_t value) {
-            this->integerValues[this->integerIdentifierToIndexMap->at(name)] = value;
+            this->identifierToValueMap[name] = value;
         }
         
         void SimpleValuation::setDoubleValue(std::string const& name, double value) {
-            this->doubleValues[this->doubleIdentifierToIndexMap->at(name)] = value;
+            this->identifierToValueMap[name] = value;
         }
         
         bool SimpleValuation::getBooleanValue(std::string const& name) const {
-            auto const& nameIndexPair = this->booleanIdentifierToIndexMap->find(name);
-            return this->booleanValues[nameIndexPair->second];
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            LOG_THROW(nameValuePair != this->identifierToValueMap.end(), storm::exceptions::InvalidAccessException, "Access to unkown identifier '" << name << "'.");
+            return boost::get<bool>(nameValuePair->second);
         }
         
         int_fast64_t SimpleValuation::getIntegerValue(std::string const& name) const {
-            auto const& nameIndexPair = this->integerIdentifierToIndexMap->find(name);
-            return this->integerValues[nameIndexPair->second];
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            LOG_THROW(nameValuePair != this->identifierToValueMap.end(), storm::exceptions::InvalidAccessException, "Access to unkown identifier '" << name << "'.");
+            return boost::get<int_fast64_t>(nameValuePair->second);
         }
         
         double SimpleValuation::getDoubleValue(std::string const& name) const {
-            auto const& nameIndexPair = this->doubleIdentifierToIndexMap->find(name);
-            return this->doubleValues[nameIndexPair->second];
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            LOG_THROW(nameValuePair != this->identifierToValueMap.end(), storm::exceptions::InvalidAccessException, "Access to unkown identifier '" << name << "'.");
+            return boost::get<double>(nameValuePair->second);
         }
         
         std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation) {
-            stream << "valuation { bool [";
-            if (!valuation.booleanValues.empty()) {
-                for (uint_fast64_t i = 0; i < valuation.booleanValues.size() - 1; ++i) {
-                    stream << valuation.booleanValues[i] << ", ";
-                }
-                stream << valuation.booleanValues.back();
-            }
-            stream << "] int [";
-            if (!valuation.integerValues.empty()) {
-                for (uint_fast64_t i = 0; i < valuation.integerValues.size() - 1; ++i) {
-                    stream << valuation.integerValues[i] << ", ";
-                }
-                stream << valuation.integerValues.back();
+            stream << "valuation { ";
+            for (auto const& nameValuePair : valuation.identifierToValueMap) {
+                stream << nameValuePair.first << ": " << nameValuePair.second << std::endl;
             }
-            stream << "] double [";
-            if (!valuation.doubleValues.empty()) {
-                for (uint_fast64_t i = 0; i < valuation.doubleValues.size() - 1; ++i) {
-                    stream << valuation.doubleValues[i] << ", ";
-                }
-                stream << valuation.doubleValues.back();
-            }
-            stream << "] }";
+            stream << "}";
             
             return stream;
         }
         
         std::size_t SimpleValuationPointerHash::operator()(SimpleValuation* valuation) const {
             size_t seed = 0;
-            for (auto const& value : valuation->booleanValues) {
-                boost::hash_combine<bool>(seed, value);
-            }
-            for (auto const& value : valuation->integerValues) {
-                boost::hash_combine<int_fast64_t>(seed, value);
-            }
-            for (auto const& value : valuation->doubleValues) {
-                boost::hash_combine<double>(seed, value);
+            for (auto const& nameValuePair : valuation->identifierToValueMap) {
+                boost::hash_combine(seed, nameValuePair.first);
+                boost::hash_combine(seed, nameValuePair.second);
             }
             return seed;
         }
@@ -107,21 +79,7 @@ namespace storm {
         }
         
         bool SimpleValuationPointerLess::operator()(SimpleValuation* valuation1, SimpleValuation* valuation2) const {
-            // Compare boolean variables.
-            bool less = valuation1->booleanValues < valuation2->booleanValues;
-            if (less) {
-                return true;
-            }
-            less = valuation1->integerValues < valuation2->integerValues;
-            if (less) {
-                return true;
-            }
-            less = valuation1->doubleValues < valuation2->doubleValues;
-            if (less) {
-                return true;
-            } else {
-                return false;
-            }
+            return valuation1->identifierToValueMap < valuation2->identifierToValueMap;
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index a196921a6..55caab46b 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -1,9 +1,8 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_SIMPLEVALUATION_H_
 #define STORM_STORAGE_EXPRESSIONS_SIMPLEVALUATION_H_
 
-#include <memory>
-#include <vector>
-#include <unordered_map>
+#include <boost/container/flat_map.hpp>
+#include <boost/variant.hpp>
 #include <iostream>
 
 #include "src/storage/expressions/Valuation.h"
@@ -16,12 +15,8 @@ namespace storm {
             friend class SimpleValuationPointerHash;
             friend class SimpleValuationPointerLess;
             
-            /*!
-             * Creates a simple valuation without any identifiers.
-            */
-            SimpleValuation();
-
             // Instantiate some constructors and assignments with their default implementations.
+            SimpleValuation() = default;
             SimpleValuation(SimpleValuation const&) = default;
             SimpleValuation& operator=(SimpleValuation const&) = default;
 #ifndef WINDOWS            
@@ -92,22 +87,7 @@ namespace storm {
 
         private:
             // A mapping of boolean identifiers to their local indices in the value container.
-            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> booleanIdentifierToIndexMap;
-            
-            // A mapping of integer identifiers to their local indices in the value container.
-            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> integerIdentifierToIndexMap;
-            
-            // A mapping of double identifiers to their local indices in the value container.
-            std::shared_ptr<std::unordered_map<std::string, uint_fast64_t>> doubleIdentifierToIndexMap;
-            
-            // The value container for all boolean identifiers.
-            std::vector<bool> booleanValues;
-            
-            // The value container for all integer identifiers.
-            std::vector<int_fast64_t> integerValues;
-            
-            // The value container for all double identifiers.
-            std::vector<double> doubleValues;
+            boost::container::flat_map<std::string, boost::variant<bool, int_fast64_t, double>> identifierToValueMap;
         };
         
         /*!

From f60ea09cf460e4fb03341513ff186c6f302a9a95 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 9 May 2014 19:37:27 +0200
Subject: [PATCH 113/147] Valuations now have methods to check whether they
 contain a given identifier.

Former-commit-id: 541c27d543866ac4c3f419a9514945a018022673
---
 src/storage/expressions/SimpleValuation.cpp | 30 +++++++++++++++++++++
 src/storage/expressions/SimpleValuation.h   | 10 +++++++
 src/storage/expressions/Valuation.h         | 25 +++++++++++++++++
 3 files changed, 65 insertions(+)

diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index f930f7e10..e8fb27611 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -37,6 +37,36 @@ namespace storm {
             this->identifierToValueMap[name] = value;
         }
         
+        void SimpleValuation::removeIdentifier(std::string const& name) {
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            LOG_THROW(nameValuePair != this->identifierToValueMap.end(), storm::exceptions::InvalidArgumentException, "Deleting unknown identifier '" << name << "'.");
+            this->identifierToValueMap.erase(nameValuePair);
+        }
+        
+        bool SimpleValuation::containsBooleanIdentifier(std::string const& name) const {
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            if (nameValuePair == this->identifierToValueMap.end()) {
+                return false;
+            }
+            return nameValuePair->second.type() == typeid(bool);
+        }
+        
+        bool SimpleValuation::containsIntegerIdentifier(std::string const& name) const {
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            if (nameValuePair == this->identifierToValueMap.end()) {
+                return false;
+            }
+            return nameValuePair->second.type() == typeid(int_fast64_t);
+        }
+        
+        bool SimpleValuation::containsDoubleIdentifier(std::string const& name) const {
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            if (nameValuePair == this->identifierToValueMap.end()) {
+                return false;
+            }
+            return nameValuePair->second.type() == typeid(double);
+        }
+        
         bool SimpleValuation::getBooleanValue(std::string const& name) const {
             auto nameValuePair = this->identifierToValueMap.find(name);
             LOG_THROW(nameValuePair != this->identifierToValueMap.end(), storm::exceptions::InvalidAccessException, "Access to unkown identifier '" << name << "'.");
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 55caab46b..0ea05a511 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -78,7 +78,17 @@ namespace storm {
              */
             void setDoubleValue(std::string const& name, double value);
             
+            /*!
+             * Removes the given identifier from this valuation.
+             *
+             * @param name The name of the identifier that is to be removed.
+             */
+            void removeIdentifier(std::string const& name);
+            
             // Override base class methods.
+            virtual bool containsBooleanIdentifier(std::string const& name) const override;
+            virtual bool containsIntegerIdentifier(std::string const& name) const override;
+            virtual bool containsDoubleIdentifier(std::string const& name) const override;
             virtual bool getBooleanValue(std::string const& name) const override;
             virtual int_fast64_t getIntegerValue(std::string const& name) const override;
             virtual double getDoubleValue(std::string const& name) const override;
diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
index 7aa32a859..19792b720 100644
--- a/src/storage/expressions/Valuation.h
+++ b/src/storage/expressions/Valuation.h
@@ -34,6 +34,31 @@ namespace storm {
              * @return The value of the double identifier.
              */
             virtual double getDoubleValue(std::string const& name) const = 0;
+            
+            /*!
+             * Retrieves whether there exists a boolean identifier with the given name in the valuation.
+             *
+             * @param name The name of the boolean identifier to query.
+             * @return True iff the identifier exists and is of boolean type.
+             */
+            virtual bool containsBooleanIdentifier(std::string const& name) const = 0;
+            
+            /*!
+             * Retrieves whether there exists a integer identifier with the given name in the valuation.
+             *
+             * @param name The name of the integer identifier to query.
+             * @return True iff the identifier exists and is of boolean type.
+             */
+            virtual bool containsIntegerIdentifier(std::string const& name) const = 0;
+            
+            /*!
+             * Retrieves whether there exists a double identifier with the given name in the valuation.
+             *
+             * @param name The name of the double identifier to query.
+             * @return True iff the identifier exists and is of boolean type.
+             */
+            virtual bool containsDoubleIdentifier(std::string const& name) const = 0;
+
         };
     }
 }

From 57a8381f914b2a8103875736c596b6c08da28bc5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 10 May 2014 15:18:19 +0200
Subject: [PATCH 114/147] If requested, the DD iterator can now skip meta
 variables which are 'don't cares' for the function value.

Former-commit-id: 061cb5f0fa0c0f3286906e9b5f01779f176674d1
---
 src/storage/dd/CuddDd.cpp                   |  8 ++--
 src/storage/dd/CuddDd.h                     |  8 +++-
 src/storage/dd/CuddDdForwardIterator.cpp    | 45 +++++++++++++++++----
 src/storage/dd/CuddDdForwardIterator.h      |  8 +++-
 src/storage/expressions/SimpleValuation.cpp |  9 ++++-
 test/functional/storage/CuddDdTest.cpp      | 22 ++++++++++
 6 files changed, 84 insertions(+), 16 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 72abb87bf..cdff92894 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -473,15 +473,15 @@ namespace storm {
             return this->ddManager;
         }
         
-        DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::begin() const {
+        DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::begin(bool enumerateDontCareMetaVariables) const {
             int* cube;
             double value;
             DdGen* generator = this->getCuddAdd().FirstCube(&cube, &value);
-            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, Cudd_IsGenEmpty(generator), &this->getContainedMetaVariableNames());
+            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, Cudd_IsGenEmpty(generator), &this->getContainedMetaVariableNames(), enumerateDontCareMetaVariables);
         }
         
-        DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::end() const {
-            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), nullptr, nullptr, 0, true, nullptr);
+        DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::end(bool enumerateDontCareMetaVariables) const {
+            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), nullptr, nullptr, 0, true, nullptr, enumerateDontCareMetaVariables);
         }
         
         std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index f345c28a2..9f638d329 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -440,16 +440,20 @@ namespace storm {
             /*!
              * Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
              *
+             * @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.
              * @return An iterator that points to the first meta variable assignment with a non-zero function value.
              */
-            DdForwardIterator<DdType::CUDD> begin() const;
+            DdForwardIterator<DdType::CUDD> begin(bool enumerateDontCareMetaVariables = true) const;
             
             /*!
              * Retrieves an iterator that points past the end of the container.
              *
+             * @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.
              * @return An iterator that points past the end of the container.
              */
-            DdForwardIterator<DdType::CUDD> end() const;
+            DdForwardIterator<DdType::CUDD> end(bool enumerateDontCareMetaVariables = true) const;
             
             friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
         private:
diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp
index 017845b47..cce5c112c 100644
--- a/src/storage/dd/CuddDdForwardIterator.cpp
+++ b/src/storage/dd/CuddDdForwardIterator.cpp
@@ -5,11 +5,11 @@
 
 namespace storm {
     namespace dd {
-        DdForwardIterator<DdType::CUDD>::DdForwardIterator() : ddManager(), generator(), cube(), value(), isAtEnd(), metaVariables(), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
+        DdForwardIterator<DdType::CUDD>::DdForwardIterator() : ddManager(), generator(), cube(), value(), isAtEnd(), metaVariables(), enumerateDontCareMetaVariables(), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
             // Intentionally left empty.
         }
         
-        DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<std::string> const* metaVariables) : ddManager(ddManager), generator(generator), cube(cube), value(value), isAtEnd(isAtEnd), metaVariables(metaVariables), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
+        DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<std::string> const* metaVariables, bool enumerateDontCareMetaVariables) : ddManager(ddManager), generator(generator), cube(cube), value(value), isAtEnd(isAtEnd), metaVariables(metaVariables), enumerateDontCareMetaVariables(enumerateDontCareMetaVariables), cubeCounter(), relevantDontCareDdVariables(), currentValuation() {
             // 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) {
@@ -113,29 +113,60 @@ namespace storm {
             // don't cares. In the latter case, we add them to a special list, so we can iterate over their concrete
             // valuations later.
             for (auto const& metaVariableName : *this->metaVariables) {
+                bool metaVariableAppearsInCube = false;
+                std::vector<std::tuple<ADD, std::string, uint_fast64_t>> localRelenvantDontCareDdVariables;
                 auto const& metaVariable = this->ddManager->getMetaVariable(metaVariableName);
                 if (metaVariable.getType() == DdMetaVariable<DdType::CUDD>::MetaVariableType::Bool) {
                     if (this->cube[metaVariable.getDdVariables()[0].getCuddAdd().NodeReadIndex()] == 0) {
-                        currentValuation.setBooleanValue(metaVariableName, false);
+                        metaVariableAppearsInCube = true;
+                        if (!currentValuation.containsBooleanIdentifier(metaVariableName)) {
+                            currentValuation.addBooleanIdentifier(metaVariableName, false);
+                        } else {
+                            currentValuation.setBooleanValue(metaVariableName, false);
+                        }
                     } else if (this->cube[metaVariable.getDdVariables()[0].getCuddAdd().NodeReadIndex()] == 1) {
-                        currentValuation.setBooleanValue(metaVariableName, true);
+                        metaVariableAppearsInCube = true;
+                        if (!currentValuation.containsBooleanIdentifier(metaVariableName)) {
+                            currentValuation.addBooleanIdentifier(metaVariableName, true);
+                        } else {
+                            currentValuation.setBooleanValue(metaVariableName, true);
+                        }
                     } else {
-                        relevantDontCareDdVariables.push_back(std::make_tuple(metaVariable.getDdVariables()[0].getCuddAdd(), metaVariableName, 0));
+                        localRelenvantDontCareDdVariables.push_back(std::make_tuple(metaVariable.getDdVariables()[0].getCuddAdd(), metaVariableName, 0));
                     }
                 } else {
                     int_fast64_t intValue = 0;
                     for (uint_fast64_t bitIndex = 0; bitIndex < metaVariable.getNumberOfDdVariables(); ++bitIndex) {
                         if (cube[metaVariable.getDdVariables()[bitIndex].getCuddAdd().NodeReadIndex()] == 0) {
                             // Leave bit unset.
+                            metaVariableAppearsInCube = true;
                         } else if (cube[metaVariable.getDdVariables()[bitIndex].getCuddAdd().NodeReadIndex()] == 1) {
                             intValue |= 1ull << (metaVariable.getNumberOfDdVariables() - bitIndex - 1);
+                            metaVariableAppearsInCube = true;
                         } else {
                             // Temporarily leave bit unset so we can iterate trough the other option later.
                             // Add the bit to the relevant don't care bits.
-                            this->relevantDontCareDdVariables.push_back(std::make_tuple(metaVariable.getDdVariables()[bitIndex].getCuddAdd(), metaVariableName, metaVariable.getNumberOfDdVariables() - bitIndex - 1));
+                            localRelenvantDontCareDdVariables.push_back(std::make_tuple(metaVariable.getDdVariables()[bitIndex].getCuddAdd(), metaVariableName, metaVariable.getNumberOfDdVariables() - bitIndex - 1));
+                        }
+                    }
+                    if (this->enumerateDontCareMetaVariables || metaVariableAppearsInCube) {
+                        if (!currentValuation.containsIntegerIdentifier(metaVariableName)) {
+                            currentValuation.addIntegerIdentifier(metaVariableName);
                         }
+                        currentValuation.setIntegerValue(metaVariableName, intValue + metaVariable.getLow());
                     }
-                    currentValuation.setIntegerValue(metaVariableName, intValue + metaVariable.getLow());
+                }
+                
+                // If all meta variables are to be enumerated or the meta variable appeared in the cube, we register the
+                // missing bits to later enumerate all possible valuations.
+                if (this->enumerateDontCareMetaVariables || metaVariableAppearsInCube) {
+                    relevantDontCareDdVariables.insert(relevantDontCareDdVariables.end(), localRelenvantDontCareDdVariables.begin(), localRelenvantDontCareDdVariables.end());
+                }
+                
+                // If the meta variable does not appear in the cube and we're not supposed to enumerate such meta variables
+                // we remove the meta variable from the valuation.
+                if (!this->enumerateDontCareMetaVariables && !metaVariableAppearsInCube) {
+                    currentValuation.removeIdentifier(metaVariableName);
                 }
             }
             
diff --git a/src/storage/dd/CuddDdForwardIterator.h b/src/storage/dd/CuddDdForwardIterator.h
index 0515475a4..8b08af929 100644
--- a/src/storage/dd/CuddDdForwardIterator.h
+++ b/src/storage/dd/CuddDdForwardIterator.h
@@ -82,8 +82,10 @@ namespace storm {
              * @param isAtEnd A flag that indicates whether the iterator is at its end and may not be moved forward any
              * more.
              * @param metaVariables The meta variables that appear in the DD.
+             * @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<std::string> const* metaVariables = nullptr);
+            DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<std::string> const* metaVariables = nullptr, bool enumerateDontCareMetaVariables = true);
             
             /*!
              * Recreates the internal information when a new cube needs to be treated.
@@ -114,6 +116,10 @@ namespace storm {
             // The set of meta variables appearing in the DD.
             std::set<std::string> const* metaVariables;
             
+            // A flag that indicates whether the iterator is supposed to enumerate meta variable valuations even if
+            // they don't influence the function value.
+            bool enumerateDontCareMetaVariables;
+            
             // A number that represents how many assignments of the current cube have already been returned previously.
             // This is needed, because cubes may represent many assignments (if they have don't care variables).
             uint_fast64_t cubeCounter;
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index e8fb27611..4a5441e99 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -86,9 +86,14 @@ namespace storm {
         }
         
         std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation) {
-            stream << "valuation { ";
+            stream << "{ ";
+            uint_fast64_t elementIndex = 0;
             for (auto const& nameValuePair : valuation.identifierToValueMap) {
-                stream << nameValuePair.first << ": " << nameValuePair.second << std::endl;
+                stream << nameValuePair.first << " -> " << nameValuePair.second << " ";
+                ++elementIndex;
+                if (elementIndex < valuation.identifierToValueMap.size()) {
+                    stream << ", ";
+                }
             }
             stream << "}";
             
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 91d14f202..ce40c94d1 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -307,4 +307,26 @@ TEST(CuddDd, ForwardIteratorTest) {
         ++numberOfValuations;
     }
     EXPECT_EQ(9, numberOfValuations);
+
+    dd = manager->getRange("x");
+    dd = dd.ite(manager->getOne(), manager->getOne());
+    ASSERT_NO_THROW(it = dd.begin());
+    ASSERT_NO_THROW(ite = dd.end());
+    numberOfValuations = 0;
+    while (it != ite) {
+        ASSERT_NO_THROW(valuationValuePair = *it);
+        ASSERT_NO_THROW(++it);
+        ++numberOfValuations;
+    }
+    EXPECT_EQ(16, numberOfValuations);
+    
+    ASSERT_NO_THROW(it = dd.begin(false));
+    ASSERT_NO_THROW(ite = dd.end());
+    numberOfValuations = 0;
+    while (it != ite) {
+        ASSERT_NO_THROW(valuationValuePair = *it);
+        ASSERT_NO_THROW(++it);
+        ++numberOfValuations;
+    }
+    EXPECT_EQ(1, numberOfValuations);
 }

From 389fddc99671eee94261dd0f24c0da058f96d467 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 10 May 2014 21:31:04 +0200
Subject: [PATCH 115/147] Added some more methods to valuations. Changed
 visitor invocation slightly. Moves ExpressionReturnType in separate file.
 Finished linearity checking visitor. Started on visitor that extracts
 coefficients of linear expressions.

Former-commit-id: 6e3d0ec9109144f2e517aa0b6034f3d18f554175
---
 src/storage/expressions/BaseExpression.cpp    | 10 --
 src/storage/expressions/BaseExpression.h      | 10 +-
 src/storage/expressions/Expression.cpp        | 17 ++--
 src/storage/expressions/Expression.h          | 15 +++
 .../expressions/ExpressionReturnType.cpp      | 15 +++
 .../expressions/ExpressionReturnType.h        | 17 ++++
 .../IdentifierSubstitutionVisitor.cpp         |  4 +-
 .../IdentifierSubstitutionVisitor.h           |  2 +-
 .../expressions/LinearCoefficientVisitor.cpp  | 70 ++++++++++++++
 .../expressions/LinearCoefficientVisitor.h    | 46 +++++++++
 .../expressions/LinearityCheckVisitor.cpp     | 93 ++++++++++++++-----
 .../expressions/LinearityCheckVisitor.h       | 10 +-
 src/storage/expressions/SimpleValuation.cpp   | 59 +++++++++++-
 src/storage/expressions/SimpleValuation.h     | 14 +++
 .../expressions/SubstitutionVisitor.cpp       |  4 +-
 src/storage/expressions/SubstitutionVisitor.h |  2 +-
 src/storage/expressions/TypeCheckVisitor.cpp  |  4 +-
 src/storage/expressions/TypeCheckVisitor.h    |  2 +-
 src/storage/expressions/Valuation.h           | 36 +++++++
 test/functional/storage/ExpressionTest.cpp    | 17 ++++
 20 files changed, 389 insertions(+), 58 deletions(-)
 create mode 100644 src/storage/expressions/ExpressionReturnType.cpp
 create mode 100644 src/storage/expressions/ExpressionReturnType.h
 create mode 100644 src/storage/expressions/LinearCoefficientVisitor.cpp
 create mode 100644 src/storage/expressions/LinearCoefficientVisitor.h

diff --git a/src/storage/expressions/BaseExpression.cpp b/src/storage/expressions/BaseExpression.cpp
index c2f4a5ac3..38a0604e2 100644
--- a/src/storage/expressions/BaseExpression.cpp
+++ b/src/storage/expressions/BaseExpression.cpp
@@ -81,16 +81,6 @@ namespace storm {
             return this->shared_from_this();
         }
         
-        std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue) {
-            switch (enumValue) {
-                case ExpressionReturnType::Undefined: stream << "undefined"; break;
-                case ExpressionReturnType::Bool: stream << "bool"; break;
-                case ExpressionReturnType::Int: stream << "int"; break;
-                case ExpressionReturnType::Double: stream << "double"; break;
-            }
-            return stream;
-        }
-        
         std::ostream& operator<<(std::ostream& stream, BaseExpression const& expression) {
             expression.printToStream(stream);
             return stream;
diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 6a02b35ab..9524fcdbb 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -6,6 +6,7 @@
 #include <set>
 #include <iostream>
 
+#include "src/storage/expressions/ExpressionReturnType.h"
 #include "src/storage/expressions/Valuation.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 #include "src/storage/expressions/OperatorType.h"
@@ -13,14 +14,7 @@
 #include "src/utility/OsDetection.h"
 
 namespace storm {
-    namespace expressions {
-        /*!
-         * Each node in an expression tree has a uniquely defined type from this enum.
-         */
-        enum class ExpressionReturnType {Undefined, Bool, Int, Double};
-        
-        std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue);
-        
+    namespace expressions {        
         /*!
          * The base class of all expression classes.
          */
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 169578c34..762ed07bf 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -5,6 +5,7 @@
 #include "src/storage/expressions/SubstitutionVisitor.h"
 #include "src/storage/expressions/IdentifierSubstitutionVisitor.h"
 #include "src/storage/expressions/TypeCheckVisitor.h"
+#include "src/storage/expressions/LinearityCheckVisitor.h"
 #include "src/storage/expressions/Expressions.h"
 #include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/ExceptionMacros.h"
@@ -16,27 +17,27 @@ namespace storm {
         }
         
 		Expression Expression::substitute(std::map<std::string, Expression> const& identifierToExpressionMap) const {
-            return SubstitutionVisitor<std::map<std::string, Expression>>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
+            return SubstitutionVisitor<std::map<std::string, Expression>>(identifierToExpressionMap).substitute(this);
         }
 
 		Expression Expression::substitute(std::unordered_map<std::string, Expression> const& identifierToExpressionMap) const {
-			return SubstitutionVisitor<std::unordered_map<std::string, Expression>>(identifierToExpressionMap).substitute(this->getBaseExpressionPointer().get());
+			return SubstitutionVisitor<std::unordered_map<std::string, Expression>>(identifierToExpressionMap).substitute(this);
 		}
         
 		Expression Expression::substitute(std::map<std::string, std::string> const& identifierToIdentifierMap) const {
-			return IdentifierSubstitutionVisitor<std::map<std::string, std::string>>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+			return IdentifierSubstitutionVisitor<std::map<std::string, std::string>>(identifierToIdentifierMap).substitute(this);
         }
 
 		Expression Expression::substitute(std::unordered_map<std::string, std::string> const& identifierToIdentifierMap) const {
-			return IdentifierSubstitutionVisitor<std::unordered_map<std::string, std::string>>(identifierToIdentifierMap).substitute(this->getBaseExpressionPointer().get());
+			return IdentifierSubstitutionVisitor<std::unordered_map<std::string, std::string>>(identifierToIdentifierMap).substitute(this);
 		}
         
         void Expression::check(std::map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const {
-            return TypeCheckVisitor<std::map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this->getBaseExpressionPointer().get());
+            return TypeCheckVisitor<std::map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this);
         }
 
         void Expression::check(std::unordered_map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const {
-            return TypeCheckVisitor<std::unordered_map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this->getBaseExpressionPointer().get());
+            return TypeCheckVisitor<std::unordered_map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this);
         }
 
         bool Expression::evaluateAsBool(Valuation const* valuation) const {
@@ -105,6 +106,10 @@ namespace storm {
             || this->getOperator() == OperatorType::Greater || this->getOperator() == OperatorType::GreaterOrEqual;
         }
         
+        bool Expression::isLinear() const {
+            return LinearityCheckVisitor().check(*this);
+        }
+        
         std::set<std::string> Expression::getVariables() const {
             return this->getBaseExpression().getVariables();
         }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index 81ae5cf54..08c758f27 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -6,6 +6,7 @@
 #include <unordered_map>
 
 #include "src/storage/expressions/BaseExpression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
 #include "src/utility/OsDetection.h"
 
 namespace storm {
@@ -238,6 +239,13 @@ namespace storm {
              */
             bool isRelationalExpression() const;
             
+            /*!
+             * Retrieves whether this expression is a linear expression.
+             *
+             * @return True iff the expression is linear.
+             */
+            bool isLinear() const;
+            
             /*!
              * Retrieves the set of all variables that appear in the expression.
              *
@@ -281,6 +289,13 @@ namespace storm {
              */
             bool hasBooleanReturnType() const;
             
+            /*!
+             * Accepts the given visitor.
+             *
+             * @param visitor The visitor to accept.
+             */
+            void accept(ExpressionVisitor* visitor) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, Expression const& expression);
 
         private:
diff --git a/src/storage/expressions/ExpressionReturnType.cpp b/src/storage/expressions/ExpressionReturnType.cpp
new file mode 100644
index 000000000..c10810f6c
--- /dev/null
+++ b/src/storage/expressions/ExpressionReturnType.cpp
@@ -0,0 +1,15 @@
+#include "src/storage/expressions/ExpressionReturnType.h"
+
+namespace storm {
+    namespace expressions {
+        std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue) {
+            switch (enumValue) {
+                case ExpressionReturnType::Undefined: stream << "undefined"; break;
+                case ExpressionReturnType::Bool: stream << "bool"; break;
+                case ExpressionReturnType::Int: stream << "int"; break;
+                case ExpressionReturnType::Double: stream << "double"; break;
+            }
+            return stream;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionReturnType.h b/src/storage/expressions/ExpressionReturnType.h
new file mode 100644
index 000000000..0cf928ed8
--- /dev/null
+++ b/src/storage/expressions/ExpressionReturnType.h
@@ -0,0 +1,17 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONRETURNTYPE_H_
+#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONRETURNTYPE_H_
+
+#include <iostream>
+
+namespace storm {
+    namespace expressions {
+        /*!
+         * Each node in an expression tree has a uniquely defined type from this enum.
+         */
+        enum class ExpressionReturnType {Undefined, Bool, Int, Double};
+        
+        std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue);
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSIONRETURNTYPE_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
index a2153af6d..19724dea1 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.cpp
@@ -13,8 +13,8 @@ namespace storm {
         }
         
 		template<typename MapType>
-        Expression IdentifierSubstitutionVisitor<MapType>::substitute(BaseExpression const* expression) {
-            expression->accept(this);
+        Expression IdentifierSubstitutionVisitor<MapType>::substitute(Expression const& expression) {
+            expression.getBaseExpression().accept(this);
             return Expression(this->expressionStack.top());
         }
         
diff --git a/src/storage/expressions/IdentifierSubstitutionVisitor.h b/src/storage/expressions/IdentifierSubstitutionVisitor.h
index 23dae79de..8e8723a70 100644
--- a/src/storage/expressions/IdentifierSubstitutionVisitor.h
+++ b/src/storage/expressions/IdentifierSubstitutionVisitor.h
@@ -26,7 +26,7 @@ namespace storm {
              * @return The expression in which all identifiers in the key set of the previously given mapping are
              * substituted with the mapped-to expressions.
              */
-            Expression substitute(BaseExpression const* expression);
+            Expression substitute(Expression const& expression);
             
             virtual void visit(IfThenElseExpression const* expression) override;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
diff --git a/src/storage/expressions/LinearCoefficientVisitor.cpp b/src/storage/expressions/LinearCoefficientVisitor.cpp
new file mode 100644
index 000000000..58fd427d5
--- /dev/null
+++ b/src/storage/expressions/LinearCoefficientVisitor.cpp
@@ -0,0 +1,70 @@
+#include "src/storage/expressions/LinearCoefficientVisitor.h"
+
+#include "src/storage/expressions/Expressions.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidArgumentException.h"
+
+namespace storm {
+    namespace expressions {
+        std::pair<SimpleValuation, double> LinearCoefficientVisitor::getLinearCoefficients(Expression const& expression) {
+            expression.getBaseExpression().accept(this);
+            return resultStack.top();
+        }
+        
+        void LinearCoefficientVisitor::visit(IfThenElseExpression const* expression) {
+            LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+        }
+        
+        void LinearCoefficientVisitor::visit(BinaryBooleanFunctionExpression const* expression) {
+            
+        }
+        
+        void LinearCoefficientVisitor::visit(BinaryNumericalFunctionExpression const* expression) {
+            
+        }
+        
+        void LinearCoefficientVisitor::visit(BinaryRelationExpression const* expression) {
+            
+        }
+        
+        void LinearCoefficientVisitor::visit(VariableExpression const* expression) {
+            SimpleValuation valuation;
+            switch (expression->getReturnType()) {
+                case ExpressionReturnType::Bool: LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear."); break;
+                case ExpressionReturnType::Int:
+                case ExpressionReturnType::Double: valuation.addDoubleIdentifier(expression->getVariableName(), 1); break;
+                case ExpressionReturnType::Undefined: LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Illegal expression return type."); break;
+            }
+            
+            resultStack.push(std::make_pair(valuation, 0));
+        }
+        
+        void LinearCoefficientVisitor::visit(UnaryBooleanFunctionExpression const* expression) {
+            LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+        }
+        
+        void LinearCoefficientVisitor::visit(UnaryNumericalFunctionExpression const* expression) {
+            if (expression->getOperatorType() == UnaryNumericalFunctionExpression::OperatorType::Minus) {
+                // Here, we need to negate all double identifiers.
+                std::pair<SimpleValuation, double>& valuationConstantPair = resultStack.top();
+                for (auto const& identifier : valuationConstantPair.first.getDoubleIdentifiers()) {
+                    valuationConstantPair.first.setDoubleValue(identifier, -valuationConstantPair.first.getDoubleValue(identifier));
+                }
+            } else {
+                LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+            }
+        }
+        
+        void LinearCoefficientVisitor::visit(BooleanLiteralExpression const* expression) {
+            LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+        }
+        
+        void LinearCoefficientVisitor::visit(IntegerLiteralExpression const* expression) {
+            resultStack.push(std::make_pair(SimpleValuation(), static_cast<double>(expression->getValue())));
+        }
+        
+        void LinearCoefficientVisitor::visit(DoubleLiteralExpression const* expression) {
+            resultStack.push(std::make_pair(SimpleValuation(), expression->getValue()));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/LinearCoefficientVisitor.h b/src/storage/expressions/LinearCoefficientVisitor.h
new file mode 100644
index 000000000..263e752c8
--- /dev/null
+++ b/src/storage/expressions/LinearCoefficientVisitor.h
@@ -0,0 +1,46 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_LINEARCOEFFICIENTVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_LINEARCOEFFICIENTVISITOR_H_
+
+#include <stack>
+
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+#include "src/storage/expressions/SimpleValuation.h"
+
+namespace storm {
+    namespace expressions {
+        class LinearCoefficientVisitor : public ExpressionVisitor {
+        public:
+            /*!
+             * Creates a linear coefficient visitor.
+             */
+            LinearCoefficientVisitor() = default;
+            
+            /*!
+             * Computes the (double) coefficients of all identifiers appearing in the expression if the expression
+             * was rewritten as a sum of atoms.. If the expression is not linear, an exception is thrown.
+             *
+             * @param expression The expression for which to compute the coefficients.
+             * @return A pair consisting of a mapping from identifiers to their coefficients and the coefficient of
+             * the constant atom.
+             */
+            std::pair<SimpleValuation, double> getLinearCoefficients(Expression const& expression);
+            
+            virtual void visit(IfThenElseExpression const* expression) override;
+            virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(BinaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BinaryRelationExpression const* expression) override;
+            virtual void visit(VariableExpression const* expression) override;
+            virtual void visit(UnaryBooleanFunctionExpression const* expression) override;
+            virtual void visit(UnaryNumericalFunctionExpression const* expression) override;
+            virtual void visit(BooleanLiteralExpression const* expression) override;
+            virtual void visit(IntegerLiteralExpression const* expression) override;
+            virtual void visit(DoubleLiteralExpression const* expression) override;
+            
+        private:
+            std::stack<std::pair<SimpleValuation, double>> resultStack;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_LINEARCOEFFICIENTVISITOR_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/LinearityCheckVisitor.cpp b/src/storage/expressions/LinearityCheckVisitor.cpp
index d4086abf1..5dd2f38ac 100644
--- a/src/storage/expressions/LinearityCheckVisitor.cpp
+++ b/src/storage/expressions/LinearityCheckVisitor.cpp
@@ -6,73 +6,124 @@
 
 namespace storm {
     namespace expressions {
-        bool LinearityCheckVisitor::check(BaseExpression const* expression) {
-            expression->accept(this);
-            return resultStack.top();
+        LinearityCheckVisitor::LinearityCheckVisitor() : resultStack() {
+            // Intentionally left empty.
+        }
+        
+        bool LinearityCheckVisitor::check(Expression const& expression) {
+            expression.getBaseExpression().accept(this);
+            return resultStack.top() == LinearityStatus::LinearWithoutVariables || resultStack.top() == LinearityStatus::LinearContainsVariables;
         }
         
         void LinearityCheckVisitor::visit(IfThenElseExpression const* expression) {
             // An if-then-else expression is never linear.
-            resultStack.push(false);
+            resultStack.push(LinearityStatus::NonLinear);
         }
         
         void LinearityCheckVisitor::visit(BinaryBooleanFunctionExpression const* expression) {
             // Boolean function applications are not allowed in linear expressions.
-            resultStack.push(false);
+            resultStack.push(LinearityStatus::NonLinear);
         }
         
         void LinearityCheckVisitor::visit(BinaryNumericalFunctionExpression const* expression) {
-            bool leftResult = true;
-            bool rightResult = true;
+            LinearityStatus leftResult;
+            LinearityStatus rightResult;
             switch (expression->getOperatorType()) {
                 case BinaryNumericalFunctionExpression::OperatorType::Plus:
                 case BinaryNumericalFunctionExpression::OperatorType::Minus:
                     expression->getFirstOperand()->accept(this);
                     leftResult = resultStack.top();
                     
-                    if (!leftResult) {
-                        
+                    if (leftResult == LinearityStatus::NonLinear) {
+                        return;
                     } else {
                         resultStack.pop();
-
                         expression->getSecondOperand()->accept(this);
+                        rightResult = resultStack.top();
+                        if (rightResult == LinearityStatus::NonLinear) {
+                            return;
+                        }
+                        resultStack.pop();
                     }
-
+                                        
+                    resultStack.push(leftResult == LinearityStatus::LinearContainsVariables || rightResult == LinearityStatus::LinearContainsVariables ? LinearityStatus::LinearContainsVariables : LinearityStatus::LinearWithoutVariables);
+                    break;
                 case BinaryNumericalFunctionExpression::OperatorType::Times:
                 case BinaryNumericalFunctionExpression::OperatorType::Divide:
-                case BinaryNumericalFunctionExpression::OperatorType::Min: resultStack.push(false); break;
-                case BinaryNumericalFunctionExpression::OperatorType::Max: resultStack.push(false); break;
+                    expression->getFirstOperand()->accept(this);
+                    leftResult = resultStack.top();
+                    
+                    if (leftResult == LinearityStatus::NonLinear) {
+                        return;
+                    } else {
+                        resultStack.pop();
+                        expression->getSecondOperand()->accept(this);
+                        rightResult = resultStack.top();
+                        if (rightResult == LinearityStatus::NonLinear) {
+                            return;
+                        }
+                        resultStack.pop();
+                    }
+                    
+                    if (leftResult == LinearityStatus::LinearContainsVariables && rightResult == LinearityStatus::LinearContainsVariables) {
+                        resultStack.push(LinearityStatus::NonLinear);
+                    }
+                    
+                    resultStack.push(leftResult == LinearityStatus::LinearContainsVariables || rightResult == LinearityStatus::LinearContainsVariables ? LinearityStatus::LinearContainsVariables : LinearityStatus::LinearWithoutVariables);
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Min: resultStack.push(LinearityStatus::NonLinear); break;
+                case BinaryNumericalFunctionExpression::OperatorType::Max: resultStack.push(LinearityStatus::NonLinear); break;
             }
         }
         
         void LinearityCheckVisitor::visit(BinaryRelationExpression const* expression) {
-            resultStack.push(false);
+            LinearityStatus leftResult;
+            LinearityStatus rightResult;
+            expression->getFirstOperand()->accept(this);
+            leftResult = resultStack.top();
+            
+            if (leftResult == LinearityStatus::NonLinear) {
+                return;
+            } else {
+                resultStack.pop();
+                expression->getSecondOperand()->accept(this);
+                rightResult = resultStack.top();
+                if (rightResult == LinearityStatus::NonLinear) {
+                    return;
+                }
+                resultStack.pop();
+            }
+            
+            resultStack.push(leftResult == LinearityStatus::LinearContainsVariables || rightResult == LinearityStatus::LinearContainsVariables ? LinearityStatus::LinearContainsVariables : LinearityStatus::LinearWithoutVariables);
         }
         
         void LinearityCheckVisitor::visit(VariableExpression const* expression) {
-            resultStack.push(true);
+            resultStack.push(LinearityStatus::LinearContainsVariables);
         }
         
         void LinearityCheckVisitor::visit(UnaryBooleanFunctionExpression const* expression) {
             // Boolean function applications are not allowed in linear expressions.
-            resultStack.push(false);
+            resultStack.push(LinearityStatus::NonLinear);
         }
         
         void LinearityCheckVisitor::visit(UnaryNumericalFunctionExpression const* expression) {
-            // Intentionally left empty (just pass subresult one level further).
+            switch (expression->getOperatorType()) {
+                case UnaryNumericalFunctionExpression::OperatorType::Minus: break;
+                case UnaryNumericalFunctionExpression::OperatorType::Floor:
+                case UnaryNumericalFunctionExpression::OperatorType::Ceil: resultStack.pop(); resultStack.push(LinearityStatus::NonLinear); break;
+            }
         }
         
         void LinearityCheckVisitor::visit(BooleanLiteralExpression const* expression) {
-            // Boolean function applications are not allowed in linear expressions.
-            resultStack.push(false);
+            resultStack.push(LinearityStatus::NonLinear);
         }
         
         void LinearityCheckVisitor::visit(IntegerLiteralExpression const* expression) {
-            resultStack.push(true);
+            resultStack.push(LinearityStatus::LinearWithoutVariables);
         }
         
         void LinearityCheckVisitor::visit(DoubleLiteralExpression const* expression) {
-            resultStack.push(true);
+            resultStack.push(LinearityStatus::LinearWithoutVariables);
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/LinearityCheckVisitor.h b/src/storage/expressions/LinearityCheckVisitor.h
index 2b1c3937c..d76b658c8 100644
--- a/src/storage/expressions/LinearityCheckVisitor.h
+++ b/src/storage/expressions/LinearityCheckVisitor.h
@@ -13,12 +13,14 @@ namespace storm {
             /*!
              * Creates a linearity check visitor.
              */
-            LinearityCheckVisitor() = default;
+            LinearityCheckVisitor();
             
             /*!
              * Checks that the given expression is linear.
+             *
+             * @param expression The expression to check for linearity.
              */
-            bool check(BaseExpression const* expression);
+            bool check(Expression const& expression);
             
             virtual void visit(IfThenElseExpression const* expression) override;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
@@ -32,8 +34,10 @@ namespace storm {
             virtual void visit(DoubleLiteralExpression const* expression) override;
             
         private:
+            enum class LinearityStatus { NonLinear, LinearContainsVariables, LinearWithoutVariables };
+            
             // A stack for communicating the results of the subexpressions.
-            std::stack<bool> resultStack;
+            std::stack<LinearityStatus> resultStack;
         };
     }
 }
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index 4a5441e99..923bbe84b 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -1,5 +1,8 @@
-#include <boost/functional/hash.hpp>
 #include "src/storage/expressions/SimpleValuation.h"
+
+#include <set>
+
+#include <boost/functional/hash.hpp>
 #include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/exceptions/InvalidAccessException.h"
@@ -43,6 +46,18 @@ namespace storm {
             this->identifierToValueMap.erase(nameValuePair);
         }
         
+        ExpressionReturnType SimpleValuation::getIdentifierType(std::string const& name) const {
+            auto nameValuePair = this->identifierToValueMap.find(name);
+            LOG_THROW(nameValuePair != this->identifierToValueMap.end(), storm::exceptions::InvalidAccessException, "Access to unkown identifier '" << name << "'.");
+            if (nameValuePair->second.type() == typeid(bool)) {
+                return ExpressionReturnType::Bool;
+            } else if (nameValuePair->second.type() == typeid(int_fast64_t)) {
+                return ExpressionReturnType::Int;
+            } else {
+                return ExpressionReturnType::Double;
+            }
+        }
+        
         bool SimpleValuation::containsBooleanIdentifier(std::string const& name) const {
             auto nameValuePair = this->identifierToValueMap.find(name);
             if (nameValuePair == this->identifierToValueMap.end()) {
@@ -85,6 +100,48 @@ namespace storm {
             return boost::get<double>(nameValuePair->second);
         }
         
+        std::size_t SimpleValuation::getNumberOfIdentifiers() const {
+            return this->identifierToValueMap.size();
+        }
+        
+        std::set<std::string> SimpleValuation::getIdentifiers() const {
+            std::set<std::string> result;
+            for (auto const& nameValuePair : this->identifierToValueMap) {
+                result.insert(nameValuePair.first);
+            }
+            return result;
+        }
+        
+        std::set<std::string> SimpleValuation::getBooleanIdentifiers() const {
+            std::set<std::string> result;
+            for (auto const& nameValuePair : this->identifierToValueMap) {
+                if (nameValuePair.second.type() == typeid(bool)) {
+                    result.insert(nameValuePair.first);
+                }
+            }
+            return result;
+        }
+        
+        std::set<std::string> SimpleValuation::getIntegerIdentifiers() const {
+            std::set<std::string> result;
+            for (auto const& nameValuePair : this->identifierToValueMap) {
+                if (nameValuePair.second.type() == typeid(int_fast64_t)) {
+                    result.insert(nameValuePair.first);
+                }
+            }
+            return result;
+        }
+        
+        std::set<std::string> SimpleValuation::getDoubleIdentifiers() const {
+            std::set<std::string> result;
+            for (auto const& nameValuePair : this->identifierToValueMap) {
+                if (nameValuePair.second.type() == typeid(double)) {
+                    result.insert(nameValuePair.first);
+                }
+            }
+            return result;
+        }
+        
         std::ostream& operator<<(std::ostream& stream, SimpleValuation const& valuation) {
             stream << "{ ";
             uint_fast64_t elementIndex = 0;
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index 0ea05a511..fccfe2faa 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -6,6 +6,7 @@
 #include <iostream>
 
 #include "src/storage/expressions/Valuation.h"
+#include "src/storage/expressions/ExpressionReturnType.h"
 #include "src/utility/OsDetection.h"
 
 namespace storm {
@@ -84,11 +85,24 @@ namespace storm {
              * @param name The name of the identifier that is to be removed.
              */
             void removeIdentifier(std::string const& name);
+
+            /*!
+             * Retrieves the type of the identifier with the given name.
+             *
+             * @param name The name of the identifier whose type to retrieve.
+             * @return The type of the identifier with the given name.
+             */
+            ExpressionReturnType getIdentifierType(std::string const& name) const;
             
             // Override base class methods.
             virtual bool containsBooleanIdentifier(std::string const& name) const override;
             virtual bool containsIntegerIdentifier(std::string const& name) const override;
             virtual bool containsDoubleIdentifier(std::string const& name) const override;
+            virtual std::size_t getNumberOfIdentifiers() const override;
+            virtual std::set<std::string> getIdentifiers() const override;
+            virtual std::set<std::string> getBooleanIdentifiers() const override;
+            virtual std::set<std::string> getIntegerIdentifiers() const override;
+            virtual std::set<std::string> getDoubleIdentifiers() const override;
             virtual bool getBooleanValue(std::string const& name) const override;
             virtual int_fast64_t getIntegerValue(std::string const& name) const override;
             virtual double getDoubleValue(std::string const& name) const override;
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index 2559b474b..43aa01ab3 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -13,8 +13,8 @@ namespace storm {
         }
 
 		template<typename MapType>
-        Expression SubstitutionVisitor<MapType>::substitute(BaseExpression const* expression) {
-            expression->accept(this);
+        Expression SubstitutionVisitor<MapType>::substitute(Expression const& expression) {
+            expression.getBaseExpression().accept(this);
             return Expression(this->expressionStack.top());
         }
         
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index bc58148e3..0ebc0941e 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -26,7 +26,7 @@ namespace storm {
              * @return The expression in which all identifiers in the key set of the previously given mapping are
              * substituted with the mapped-to expressions.
              */
-            Expression substitute(BaseExpression const* expression);
+            Expression substitute(Expression const& expression);
             
             virtual void visit(IfThenElseExpression const* expression) override;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
diff --git a/src/storage/expressions/TypeCheckVisitor.cpp b/src/storage/expressions/TypeCheckVisitor.cpp
index 044b85237..5ab80e141 100644
--- a/src/storage/expressions/TypeCheckVisitor.cpp
+++ b/src/storage/expressions/TypeCheckVisitor.cpp
@@ -12,8 +12,8 @@ namespace storm {
         }
         
         template<typename MapType>
-        void TypeCheckVisitor<MapType>::check(BaseExpression const* expression) {
-            expression->accept(this);
+        void TypeCheckVisitor<MapType>::check(Expression const& expression) {
+            expression.getBaseExpression().accept(this);
         }
         
         template<typename MapType>
diff --git a/src/storage/expressions/TypeCheckVisitor.h b/src/storage/expressions/TypeCheckVisitor.h
index 7772e0e7e..0cbf40f92 100644
--- a/src/storage/expressions/TypeCheckVisitor.h
+++ b/src/storage/expressions/TypeCheckVisitor.h
@@ -24,7 +24,7 @@ namespace storm {
              *
              * @param expression The expression in which to check the types.
              */
-            void check(BaseExpression const* expression);
+            void check(Expression const& expression);
             
             virtual void visit(IfThenElseExpression const* expression) override;
             virtual void visit(BinaryBooleanFunctionExpression const* expression) override;
diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
index 19792b720..baf39462f 100644
--- a/src/storage/expressions/Valuation.h
+++ b/src/storage/expressions/Valuation.h
@@ -58,6 +58,42 @@ namespace storm {
              * @return True iff the identifier exists and is of boolean type.
              */
             virtual bool containsDoubleIdentifier(std::string const& name) const = 0;
+            
+            /*!
+             * Retrieves the number of identifiers in this valuation.
+             *
+             * @return The number of identifiers in this valuation.
+             */
+            virtual std::size_t getNumberOfIdentifiers() const = 0;
+            
+            /*!
+             * Retrieves the set of all identifiers contained in this valuation.
+             *
+             * @return The set of all identifiers contained in this valuation.
+             */
+            virtual std::set<std::string> getIdentifiers() const = 0;
+            
+            /*!
+             * Retrieves the set of boolean identifiers contained in this valuation.
+             *
+             * @return The set of boolean identifiers contained in this valuation.
+             */
+            virtual std::set<std::string> getBooleanIdentifiers() const = 0;
+
+            /*!
+             * Retrieves the set of integer identifiers contained in this valuation.
+             *
+             * @return The set of integer identifiers contained in this valuation.
+             */
+            virtual std::set<std::string> getIntegerIdentifiers() const = 0;
+
+            /*!
+             * Retrieves the set of double identifiers contained in this valuation.
+             *
+             * @return The set of double identifiers contained in this valuation.
+             */
+            virtual std::set<std::string> getDoubleIdentifiers() const = 0;
+
 
         };
     }
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index 26822190d..d3a920d1d 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -3,6 +3,7 @@
 
 #include "gtest/gtest.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/LinearityCheckVisitor.h"
 #include "src/storage/expressions/SimpleValuation.h"
 #include "src/exceptions/InvalidTypeException.h"
 
@@ -332,4 +333,20 @@ TEST(Expression, SimpleEvaluationTest) {
     ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
     ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
     EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
+}
+
+TEST(Expression, VisitorTest) {
+    storm::expressions::Expression threeExpression;
+    storm::expressions::Expression piExpression;
+    storm::expressions::Expression intVarExpression;
+    storm::expressions::Expression doubleVarExpression;
+    
+    ASSERT_NO_THROW(threeExpression = storm::expressions::Expression::createIntegerLiteral(3));
+    ASSERT_NO_THROW(piExpression = storm::expressions::Expression::createDoubleLiteral(3.14));
+    ASSERT_NO_THROW(intVarExpression = storm::expressions::Expression::createIntegerVariable("y"));
+    ASSERT_NO_THROW(doubleVarExpression = storm::expressions::Expression::createDoubleVariable("z"));
+    
+    storm::expressions::Expression tempExpression = intVarExpression + doubleVarExpression * threeExpression;
+    storm::expressions::LinearityCheckVisitor visitor;
+    EXPECT_TRUE(visitor.check(tempExpression));
 }
\ No newline at end of file

From d5c2f9248fb183ee4864b8177a24082d81b3a34b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 10 May 2014 23:30:02 +0200
Subject: [PATCH 116/147] Finished linear coefficient visitor and adapted glpk
 solver to new expression-based LP solver interface.

Former-commit-id: ba1d3a912f8bebe6d388f59198870d5b060391c5
---
 src/solver/GlpkLpSolver.cpp                   | 42 ++++++---
 .../expressions/LinearCoefficientVisitor.cpp  | 87 ++++++++++++++++++-
 .../expressions/LinearityCheckVisitor.cpp     | 19 +---
 3 files changed, 117 insertions(+), 31 deletions(-)

diff --git a/src/solver/GlpkLpSolver.cpp b/src/solver/GlpkLpSolver.cpp
index fc2c5f261..1cffa1a18 100644
--- a/src/solver/GlpkLpSolver.cpp
+++ b/src/solver/GlpkLpSolver.cpp
@@ -4,6 +4,8 @@
 
 #include <iostream>
 
+#include "src/storage/expressions/LinearCoefficientVisitor.h"
+
 #include "src/settings/Settings.h"
 #include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/InvalidAccessException.h"
@@ -160,26 +162,46 @@ namespace storm {
             LOG_THROW(constraint.isRelationalExpression(), storm::exceptions::InvalidArgumentException, "Illegal constraint is not a relational expression.");
             LOG_THROW(constraint.getOperator() != storm::expressions::OperatorType::NotEqual, storm::exceptions::InvalidArgumentException, "Illegal constraint uses inequality operator.");
             
-            // TODO: get variable/coefficients vector from constraint.
+            std::pair<storm::expressions::SimpleValuation, double> leftCoefficients = storm::expressions::LinearCoefficientVisitor().getLinearCoefficients(constraint.getOperand(0));
+            std::pair<storm::expressions::SimpleValuation, double> rightCoefficients = storm::expressions::LinearCoefficientVisitor().getLinearCoefficients(constraint.getOperand(1));
+            for (auto const& identifier : rightCoefficients.first.getDoubleIdentifiers()) {
+                if (leftCoefficients.first.containsDoubleIdentifier(identifier)) {
+                    leftCoefficients.first.setDoubleValue(identifier, leftCoefficients.first.getDoubleValue(identifier) - rightCoefficients.first.getDoubleValue(identifier));
+                } else {
+                    leftCoefficients.first.addDoubleIdentifier(identifier, -rightCoefficients.first.getDoubleValue(identifier));
+                }
+            }
+            rightCoefficients.second -= leftCoefficients.second;
             
+            // Now we need to transform the coefficients to the vector representation.
+            std::vector<int> variables;
+            std::vector<double> coefficients;
+            for (auto const& identifier : leftCoefficients.first.getDoubleIdentifiers()) {
+                auto identifierIndexPair = this->variableNameToIndexMap.find(identifier);
+                LOG_THROW(identifierIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Constraint contains illegal identifier '" << identifier << "'.");
+                variables.push_back(identifierIndexPair->second);
+                coefficients.push_back(leftCoefficients.first.getDoubleValue(identifier));
+            }
             
             // Determine the type of the constraint and add it properly.
             switch (constraint.getOperator()) {
                 case storm::expressions::OperatorType::Less:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightHandSideValue - storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble());
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightCoefficients.second - storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble());
                     break;
-                case LESS_EQUAL:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightHandSideValue);
+                case storm::expressions::OperatorType::LessOrEqual:
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightCoefficients.second);
                     break;
-                case GREATER:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightHandSideValue + storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), 0);
+                case storm::expressions::OperatorType::Greater:
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightCoefficients.second + storm::settings::Settings::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), 0);
                     break;
-                case GREATER_EQUAL:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightHandSideValue, 0);
+                case storm::expressions::OperatorType::GreaterOrEqual:
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightCoefficients.second, 0);
                     break;
-                case EQUAL:
-                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_FX, rightHandSideValue, rightHandSideValue);
+                case storm::expressions::OperatorType::Equal:
+                    glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_FX, rightCoefficients.second, rightCoefficients.second);
                     break;
+                default:
+                    LOG_ASSERT(false, "Illegal operator in LP solver constraint.");
             }
             
             // Record the variables and coefficients in the coefficient matrix.
diff --git a/src/storage/expressions/LinearCoefficientVisitor.cpp b/src/storage/expressions/LinearCoefficientVisitor.cpp
index 58fd427d5..f59804927 100644
--- a/src/storage/expressions/LinearCoefficientVisitor.cpp
+++ b/src/storage/expressions/LinearCoefficientVisitor.cpp
@@ -16,15 +16,96 @@ namespace storm {
         }
         
         void LinearCoefficientVisitor::visit(BinaryBooleanFunctionExpression const* expression) {
-            
+            LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
         }
         
         void LinearCoefficientVisitor::visit(BinaryNumericalFunctionExpression const* expression) {
-            
+            if (expression->getOperatorType() == BinaryNumericalFunctionExpression::OperatorType::Plus) {
+                expression->getFirstOperand()->accept(this);
+                std::pair<SimpleValuation, double> leftResult = resultStack.top();
+                resultStack.pop();
+                expression->getSecondOperand()->accept(this);
+                std::pair<SimpleValuation, double>& rightResult = resultStack.top();
+                
+                // Now add the left result to the right result.
+                for (auto const& identifier : leftResult.first.Valuation::getDoubleIdentifiers()) {
+                    if (rightResult.first.containsDoubleIdentifier(identifier)) {
+                        rightResult.first.setDoubleValue(identifier, leftResult.first.getDoubleValue(identifier) + rightResult.first.getDoubleValue(identifier));
+                    } else {
+                        rightResult.first.setDoubleValue(identifier, leftResult.first.getDoubleValue(identifier));
+                    }
+                }
+                rightResult.second += leftResult.second;
+                return;
+            } else if (expression->getOperatorType() == BinaryNumericalFunctionExpression::OperatorType::Minus) {
+                expression->getFirstOperand()->accept(this);
+                std::pair<SimpleValuation, double> leftResult = resultStack.top();
+                resultStack.pop();
+                expression->getSecondOperand()->accept(this);
+                std::pair<SimpleValuation, double>& rightResult = resultStack.top();
+                
+                // Now subtract the right result from the left result.
+                for (auto const& identifier : leftResult.first.getDoubleIdentifiers()) {
+                    if (rightResult.first.containsDoubleIdentifier(identifier)) {
+                        rightResult.first.setDoubleValue(identifier, leftResult.first.getDoubleValue(identifier) - rightResult.first.getDoubleValue(identifier));
+                    } else {
+                        rightResult.first.setDoubleValue(identifier, leftResult.first.getDoubleValue(identifier));
+                    }
+                }
+                for (auto const& identifier : rightResult.first.Valuation::getDoubleIdentifiers()) {
+                    if (!leftResult.first.containsDoubleIdentifier(identifier)) {
+                        rightResult.first.setDoubleValue(identifier, -rightResult.first.getDoubleValue(identifier));
+                    }
+                }
+                rightResult.second = leftResult.second - rightResult.second;
+                return;
+            } else if (expression->getOperatorType() == BinaryNumericalFunctionExpression::OperatorType::Times) {
+                expression->getFirstOperand()->accept(this);
+                std::pair<SimpleValuation, double> leftResult = resultStack.top();
+                resultStack.pop();
+                expression->getSecondOperand()->accept(this);
+                std::pair<SimpleValuation, double>& rightResult = resultStack.top();
+                
+                // If the expression is linear, either the left or the right side must not contain variables.
+                LOG_THROW(leftResult.first.getNumberOfIdentifiers() == 0 || rightResult.first.getNumberOfIdentifiers() == 0, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+                if (leftResult.first.getNumberOfIdentifiers() == 0) {
+                    for (auto const& identifier : rightResult.first.getDoubleIdentifiers()) {
+                        rightResult.first.setDoubleValue(identifier, leftResult.second * rightResult.first.getDoubleValue(identifier));
+                    }
+                } else {
+                    for (auto const& identifier : leftResult.first.getDoubleIdentifiers()) {
+                        rightResult.first.addDoubleIdentifier(identifier, rightResult.second * leftResult.first.getDoubleValue(identifier));
+                    }
+                }
+                rightResult.second *= leftResult.second;
+                return;
+            } else if (expression->getOperatorType() == BinaryNumericalFunctionExpression::OperatorType::Divide) {
+                expression->getFirstOperand()->accept(this);
+                std::pair<SimpleValuation, double> leftResult = resultStack.top();
+                resultStack.pop();
+                expression->getSecondOperand()->accept(this);
+                std::pair<SimpleValuation, double>& rightResult = resultStack.top();
+                
+                // If the expression is linear, either the left or the right side must not contain variables.
+                LOG_THROW(leftResult.first.getNumberOfIdentifiers() == 0 || rightResult.first.getNumberOfIdentifiers() == 0, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+                if (leftResult.first.getNumberOfIdentifiers() == 0) {
+                    for (auto const& identifier : rightResult.first.getDoubleIdentifiers()) {
+                        rightResult.first.setDoubleValue(identifier, leftResult.second / rightResult.first.getDoubleValue(identifier));
+                    }
+                } else {
+                    for (auto const& identifier : leftResult.first.getDoubleIdentifiers()) {
+                        rightResult.first.addDoubleIdentifier(identifier, leftResult.first.getDoubleValue(identifier) / rightResult.second);
+                    }
+                }
+                rightResult.second = leftResult.second / leftResult.second;
+                return;
+            } else {
+                LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
+            }
         }
         
         void LinearCoefficientVisitor::visit(BinaryRelationExpression const* expression) {
-            
+            LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
         }
         
         void LinearCoefficientVisitor::visit(VariableExpression const* expression) {
diff --git a/src/storage/expressions/LinearityCheckVisitor.cpp b/src/storage/expressions/LinearityCheckVisitor.cpp
index 5dd2f38ac..9b382ed22 100644
--- a/src/storage/expressions/LinearityCheckVisitor.cpp
+++ b/src/storage/expressions/LinearityCheckVisitor.cpp
@@ -77,24 +77,7 @@ namespace storm {
         }
         
         void LinearityCheckVisitor::visit(BinaryRelationExpression const* expression) {
-            LinearityStatus leftResult;
-            LinearityStatus rightResult;
-            expression->getFirstOperand()->accept(this);
-            leftResult = resultStack.top();
-            
-            if (leftResult == LinearityStatus::NonLinear) {
-                return;
-            } else {
-                resultStack.pop();
-                expression->getSecondOperand()->accept(this);
-                rightResult = resultStack.top();
-                if (rightResult == LinearityStatus::NonLinear) {
-                    return;
-                }
-                resultStack.pop();
-            }
-            
-            resultStack.push(leftResult == LinearityStatus::LinearContainsVariables || rightResult == LinearityStatus::LinearContainsVariables ? LinearityStatus::LinearContainsVariables : LinearityStatus::LinearWithoutVariables);
+            resultStack.push(LinearityStatus::NonLinear);
         }
         
         void LinearityCheckVisitor::visit(VariableExpression const* expression) {

From 29d8111991a11fdc91092214b05b94b4eb89c9bc Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 11 May 2014 19:12:20 +0200
Subject: [PATCH 117/147] Adapted Gurobi and glpk LP solvers to
 expression-based interface. Adapted tests and made them work again.

Former-commit-id: 62379ddafd41487e86e55495a797540505184ada
---
 .../SparseMarkovAutomatonCslModelChecker.cpp  |  14 +-
 .../SparseMarkovAutomatonCslModelChecker.h    |   2 +-
 src/solver/GlpkLpSolver.cpp                   |  93 ++---
 src/solver/GlpkLpSolver.h                     |  18 +-
 src/solver/GurobiLpSolver.cpp                 | 386 +++++++-----------
 src/solver/GurobiLpSolver.h                   |  16 +-
 src/solver/LpSolver.h                         |   6 +-
 src/storage/expressions/Expression.cpp        |  12 +-
 .../expressions/LinearCoefficientVisitor.cpp  |   4 +-
 src/storage/expressions/Valuation.h           |   1 -
 test/functional/solver/GlpkLpSolverTest.cpp   | 243 ++++++-----
 test/functional/solver/GurobiLpSolverTest.cpp | 240 +++++------
 12 files changed, 451 insertions(+), 584 deletions(-)

diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
index 82590e31e..580ea9c69 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
@@ -1,8 +1,8 @@
-#include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h"
+// #include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h"
 
-bool SparseMarkovAutomatonCslModelCheckerOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
-    
-	instance->addOption(storm::settings::OptionBuilder("GmmxxLinearEquationSolver", "digiprecision", "", "Precision used for iterative solving of linear equation systems").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("precision value", "Precision").setDefaultValueDouble(1e-4).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
-    
-	return true;
-});
\ No newline at end of file
+//bool SparseMarkovAutomatonCslModelCheckerOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
+//    
+//	instance->addOption(storm::settings::OptionBuilder("GmmxxLinearEquationSolver", "digiprecision", "", "Precision used for iterative solving of linear equation systems").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("precision value", "Precision").setDefaultValueDouble(1e-4).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
+//    
+//	return true;
+//});
diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
index aab76f807..8a924ba47 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
@@ -428,7 +428,7 @@ namespace storm {
                  */
                 static ValueType computeLraForMaximalEndComponent(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec, uint_fast64_t mecIndex = 0) {
                     std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC");
-                    solver->setModelSense(min ? storm::solver::LpSolver::MAXIMIZE : storm::solver::LpSolver::MINIMIZE);
+                    solver->setModelSense(min ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
                     
                     // First, we need to create the variables for the problem.
                     std::map<uint_fast64_t, uint_fast64_t> stateToVariableIndexMap;
diff --git a/src/solver/GlpkLpSolver.cpp b/src/solver/GlpkLpSolver.cpp
index 1cffa1a18..2a9eec7f6 100644
--- a/src/solver/GlpkLpSolver.cpp
+++ b/src/solver/GlpkLpSolver.cpp
@@ -21,7 +21,7 @@ bool GlpkLpSolverOptionsRegistered = storm::settings::Settings::registerNewModul
 
 namespace storm {
     namespace solver {
-        GlpkLpSolver::GlpkLpSolver(std::string const& name, ModelSense const& modelSense) : LpSolver(modelSense), lp(nullptr), variableNameToIndexMap(), nextVariableIndex(0), nextConstraintIndex(0), modelContainsIntegerVariables(false), isInfeasibleFlag(false), isUnboundedFlag(false), rowIndices(), columnIndices(), coefficientValues() {
+        GlpkLpSolver::GlpkLpSolver(std::string const& name, ModelSense const& modelSense) : LpSolver(modelSense), lp(nullptr), variableNameToIndexMap(), nextVariableIndex(1), nextConstraintIndex(1), modelContainsIntegerVariables(false), isInfeasibleFlag(false), isUnboundedFlag(false), rowIndices(), columnIndices(), coefficientValues() {
             // Create the LP problem for glpk.
             lp = glp_create_prob();
             
@@ -37,11 +37,11 @@ namespace storm {
             coefficientValues.push_back(0);
         }
         
-        GlpkLpSolver::GlpkLpSolver(std::string const& name) : GlpkLpSolver(name, ModelSense::MINIMIZE) {
+        GlpkLpSolver::GlpkLpSolver(std::string const& name) : GlpkLpSolver(name, ModelSense::Minimize) {
             // Intentionally left empty.
         }
         
-        GlpkLpSolver::GlpkLpSolver() : GlpkLpSolver("", ModelSense::MINIMIZE) {
+        GlpkLpSolver::GlpkLpSolver() : GlpkLpSolver("", ModelSense::Minimize) {
             // Intentionally left empty.
         }
         
@@ -56,98 +56,65 @@ namespace storm {
         }
         
         void GlpkLpSolver::addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_DB, lowerBound, upperBound);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_CV, GLP_DB, lowerBound, upperBound, objectiveFunctionCoefficient);
         }
         
         void GlpkLpSolver::addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_LO, lowerBound, 0);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_CV, GLP_LO, lowerBound, 0, objectiveFunctionCoefficient);
         }
         
         void GlpkLpSolver::addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_UP, 0, upperBound);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_CV, GLP_UP, 0, upperBound, objectiveFunctionCoefficient);
         }
         
         void GlpkLpSolver::addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_CV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_CV, GLP_FR, 0, 0, objectiveFunctionCoefficient);
         }
         
         void GlpkLpSolver::addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_DB, lowerBound, upperBound);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_IV, GLP_DB, lowerBound, upperBound, objectiveFunctionCoefficient);
             this->modelContainsIntegerVariables = true;
         }
         
         void GlpkLpSolver::addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_LO, lowerBound, 0);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_IV, GLP_LO, lowerBound, 0, objectiveFunctionCoefficient);
             this->modelContainsIntegerVariables = true;
         }
 
         void GlpkLpSolver::addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_UP, 0, upperBound);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_IV, GLP_UP, 0, upperBound, objectiveFunctionCoefficient);
             this->modelContainsIntegerVariables = true;
         }
         
         void GlpkLpSolver::addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient) {
-            glp_add_cols(this->lp, 1);
-            glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_IV);
-            glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
-            this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
-            ++this->nextVariableIndex;
+            this->addVariable(name, GLP_IV, GLP_FR, 0, 0, objectiveFunctionCoefficient);
             this->modelContainsIntegerVariables = true;
         }
         
         void GlpkLpSolver::addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GLP_BV, GLP_FR, 0, 0, objectiveFunctionCoefficient);
+            this->modelContainsIntegerVariables = true;
+        }
+        
+        void GlpkLpSolver::addVariable(std::string const& name, int variableType, int boundType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
+            // Check whether variable already exists.
+            auto nameIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(nameIndexPair == this->variableNameToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Variable '" << nameIndexPair->first << "' already exists.");
+            
+            // Check for valid variable type.
+            LOG_ASSERT(variableType == GLP_CV || variableType == GLP_IV || variableType == GLP_BV, "Illegal type '" << variableType << "' for glpk variable.");
+            
+            // Check for valid bound type.
+            LOG_ASSERT(boundType == GLP_FR || boundType == GLP_UP || boundType == GLP_LO || boundType == GLP_DB, "Illegal bound type for variable '" << name << "'.");
+            
+            // Finally, create the actual variable.
             glp_add_cols(this->lp, 1);
             glp_set_col_name(this->lp, nextVariableIndex, name.c_str());
-            glp_set_col_bnds(lp, nextVariableIndex, GLP_FR, 0, 0);
-            glp_set_col_kind(this->lp, nextVariableIndex, GLP_BV);
+            glp_set_col_bnds(lp, nextVariableIndex, boundType, lowerBound, upperBound);
+            glp_set_col_kind(this->lp, nextVariableIndex, variableType);
             glp_set_obj_coef(this->lp, nextVariableIndex, objectiveFunctionCoefficient);
             this->variableNameToIndexMap.emplace(name, this->nextVariableIndex);
             ++this->nextVariableIndex;
-            this->modelContainsIntegerVariables = true;
         }
         
         void GlpkLpSolver::update() const {
@@ -219,7 +186,7 @@ namespace storm {
             this->isUnboundedFlag = false;
             
             // Start by setting the model sense.
-            glp_set_obj_dir(this->lp, this->getModelSense() == LpSolver::ModelSense::MINIMIZE ? GLP_MIN : GLP_MAX);
+            glp_set_obj_dir(this->lp, this->getModelSense() == LpSolver::ModelSense::Minimize ? GLP_MIN : GLP_MAX);
             
             glp_load_matrix(this->lp, rowIndices.size() - 1, rowIndices.data(), columnIndices.data(), coefficientValues.data());
             
diff --git a/src/solver/GlpkLpSolver.h b/src/solver/GlpkLpSolver.h
index 0045ced73..1f6d7bd2a 100644
--- a/src/solver/GlpkLpSolver.h
+++ b/src/solver/GlpkLpSolver.h
@@ -92,17 +92,29 @@ namespace storm {
             virtual void writeModelToFile(std::string const& filename) const override;
             
         private:
+            /*!
+             * Adds a variable with the given name, type, lower and upper bound and objective function coefficient.
+             *
+             * @param name The name of the variable.
+             * @param variableType The type of the variable in terms of glpk's constants.
+             * @param boundType A glpk flag indicating which bounds apply to the variable.
+             * @param lowerBound The lower bound of the range of the variable.
+             * @param upperBound The upper bound of the range of the variable.
+             * @param objectiveFunctionCoefficient The coefficient of the variable in the objective function.
+             */
+            void addVariable(std::string const& name, int variableType, int boundType, double lowerBound, double upperBound, double objectiveFunctionCoefficient);
+            
             // The glpk LP problem.
             glp_prob* lp;
             
             // A mapping from variable names to their indices.
-            std::map<std::string, uint_fast64_t> variableNameToIndexMap;
+            std::map<std::string, int> variableNameToIndexMap;
             
             // A counter used for getting the next variable index.
-            uint_fast64_t nextVariableIndex;
+            int nextVariableIndex;
             
             // A counter used for getting the next constraint index.
-            uint_fast64_t nextConstraintIndex;
+            int nextConstraintIndex;
             
             // A flag storing whether the model is an LP or an MILP.
             bool modelContainsIntegerVariables;
diff --git a/src/solver/GurobiLpSolver.cpp b/src/solver/GurobiLpSolver.cpp
index 75a0d5a7e..676867ecb 100644
--- a/src/solver/GurobiLpSolver.cpp
+++ b/src/solver/GurobiLpSolver.cpp
@@ -3,13 +3,12 @@
 #ifdef STORM_HAVE_GUROBI
 #include <numeric>
 
-#include "src/exceptions/InvalidStateException.h"
-#include "src/settings/Settings.h"
+#include "src/storage/expressions/LinearCoefficientVisitor.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-
-extern log4cplus::Logger logger;
+#include "src/settings/Settings.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/InvalidStateException.h"
+#include "src/exceptions/InvalidAccessException.h"
 
 bool GurobiLpSolverOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
     instance->addOption(storm::settings::OptionBuilder("GurobiLpSolver", "gurobithreads", "", "The number of threads that may be used by Gurobi.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The number of threads.").setDefaultValueUnsignedInteger(1).build()).build());
@@ -43,7 +42,7 @@ namespace storm {
             }
         }
         
-        GurobiLpSolver::GurobiLpSolver(std::string const& name) : GurobiLpSolver(name, MINIMIZE) {
+        GurobiLpSolver::GurobiLpSolver(std::string const& name) : GurobiLpSolver(name, ModelSense::Minimize) {
             // Intentionally left empty.
         }
         
@@ -51,7 +50,7 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        GurobiLpSolver::GurobiLpSolver() : GurobiLpSolver("", MINIMIZE) {
+        GurobiLpSolver::GurobiLpSolver() : GurobiLpSolver("", ModelSense::Minimize) {
             // Intentionally left empty.
         }
         
@@ -66,145 +65,124 @@ namespace storm {
 
 			// Enable the following line to only print the output of Gurobi if the debug flag is set.
             error = GRBsetintparam(env, "OutputFlag", storm::settings::Settings::getInstance()->isSet("debug") || storm::settings::Settings::getInstance()->isSet("gurobioutput") ? 1 : 0);
-			if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to set Gurobi Parameter OutputFlag (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi Parameter OutputFlag (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-			}
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi Parameter OutputFlag (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             // Enable the following line to restrict Gurobi to one thread only.
             error = GRBsetintparam(env, "Threads", storm::settings::Settings::getInstance()->getOptionByLongName("gurobithreads").getArgument(0).getValueAsUnsignedInteger());
-			if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to set Gurobi Parameter Threads (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi Parameter Threads (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-			}
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi Parameter Threads (" << GRBgeterrormsg(env) << ", error code " << error << ").");
 
             // Enable the following line to force Gurobi to be as precise about the binary variables as required by the given precision option.
             error = GRBsetdblparam(env, "IntFeasTol", storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble());
-			if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to set Gurobi Parameter IntFeasTol (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi Parameter IntFeasTol (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-			}
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi Parameter IntFeasTol (" << GRBgeterrormsg(env) << ", error code " << error << ").");
         }
         
         void GurobiLpSolver::update() const {
             int error = GRBupdatemodel(model);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to update Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to update Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to update Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             // Since the model changed, we erase the optimality flag.
             this->currentModelHasBeenOptimized = false;
         }
         
-        uint_fast64_t GurobiLpSolver::createContinuousVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
-            int error = 0;
-            switch (variableType) {
-                case LpSolver::BOUNDED:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, lowerBound, upperBound, GRB_CONTINUOUS, name.c_str());
-                    break;
-                case LpSolver::UNBOUNDED:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, -GRB_INFINITY, GRB_INFINITY, GRB_CONTINUOUS, name.c_str());
-                    break;
-                case LpSolver::UPPER_BOUND:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, -GRB_INFINITY, upperBound, GRB_CONTINUOUS, name.c_str());
-                    break;
-                case LpSolver::LOWER_BOUND:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, lowerBound, GRB_INFINITY, GRB_CONTINUOUS, name.c_str());
-                    break;
-            }
-            
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
-            ++nextVariableIndex;
-            return nextVariableIndex - 1;
+        void GurobiLpSolver::addBoundedContinuousVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_CONTINUOUS, lowerBound, upperBound, objectiveFunctionCoefficient);
         }
         
-        uint_fast64_t GurobiLpSolver::createIntegerVariable(std::string const& name, VariableType const& variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
-            int error = 0;
-            switch (variableType) {
-                case LpSolver::BOUNDED:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, lowerBound, upperBound, GRB_INTEGER, name.c_str());
-                    break;
-                case LpSolver::UNBOUNDED:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, -GRB_INFINITY, GRB_INFINITY, GRB_INTEGER, name.c_str());
-                    break;
-                case LpSolver::UPPER_BOUND:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, -GRB_INFINITY, upperBound, GRB_INTEGER, name.c_str());
-                    break;
-                case LpSolver::LOWER_BOUND:
-                    error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, lowerBound, GRB_INFINITY, GRB_INTEGER, name.c_str());
-                    break;
-            }
+        void GurobiLpSolver::addLowerBoundedContinuousVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_CONTINUOUS, lowerBound, GRB_INFINITY, objectiveFunctionCoefficient);
+        }
 
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
-            ++nextVariableIndex;
-            return nextVariableIndex - 1;
+        void GurobiLpSolver::addUpperBoundedContinuousVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_CONTINUOUS, -GRB_INFINITY, upperBound, objectiveFunctionCoefficient);
+        }
+
+        void GurobiLpSolver::addUnboundedContinuousVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_CONTINUOUS, -GRB_INFINITY, GRB_INFINITY, objectiveFunctionCoefficient);
         }
         
-        uint_fast64_t GurobiLpSolver::createBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) {
-            int error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, 0.0, 1.0, GRB_BINARY, name.c_str());
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
-            ++nextVariableIndex;
-            return nextVariableIndex - 1;
+        void GurobiLpSolver::addBoundedIntegerVariable(std::string const& name, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_INTEGER, lowerBound, upperBound, objectiveFunctionCoefficient);
         }
         
-        void GurobiLpSolver::addConstraint(std::string const& name, std::vector<uint_fast64_t> const& variables, std::vector<double> const& coefficients, BoundType const& boundType, double rightHandSideValue) {
-            if (variables.size() != coefficients.size()) {
-                LOG4CPLUS_ERROR(logger, "Sizes of variable indices vector and coefficients vector do not match.");
-                throw storm::exceptions::InvalidStateException() << "Sizes of variable indices vector and coefficients vector do not match.";
-            }
+        void GurobiLpSolver::addLowerBoundedIntegerVariable(std::string const& name, double lowerBound, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_INTEGER, lowerBound, GRB_INFINITY, objectiveFunctionCoefficient);
+        }
+        
+        void GurobiLpSolver::addUpperBoundedIntegerVariable(std::string const& name, double upperBound, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_INTEGER, -GRB_INFINITY, upperBound, objectiveFunctionCoefficient);
+        }
+        
+        void GurobiLpSolver::addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_INTEGER, -GRB_INFINITY, GRB_INFINITY, objectiveFunctionCoefficient);
+        }
+        
+        void GurobiLpSolver::addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) {
+            this->addVariable(name, GRB_BINARY, 0, 1, objectiveFunctionCoefficient);
+        }
+
+        void GurobiLpSolver::addVariable(std::string const& name, char variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient) {
+            // Check whether variable already exists.
+            auto nameIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(nameIndexPair == this->variableNameToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Variable '" << nameIndexPair->first << "' already exists.");
             
-            // As Gurobi requires the indices to be unique, we now explicitly make them unique. For this, we sort the
-            // variables and coefficients and eliminated duplicates by adding the coefficients.
+            // Check for valid variable type.
+            LOG_ASSERT(variableType == GRB_CONTINUOUS || variableType == GRB_INTEGER || variableType == GRB_BINARY, "Illegal type '" << variableType << "' for Gurobi variable.");
             
-            // We start by sorting both vectors.
-            std::vector<uint_fast64_t> sortedVariables(variables);
-			std::vector<double> sortedCoefficients(coefficients);
-            std::vector<uint_fast64_t> permutation(variables.size());
-            std::iota(permutation.begin(), permutation.end(), 0);
-            std::sort(permutation.begin(), permutation.end(), [&] (uint_fast64_t i, uint_fast64_t j) { return variables[i] < variables[j]; } );
-            std::transform(permutation.begin(), permutation.end(), sortedVariables.begin(), [&] (uint_fast64_t i) { return variables[i]; } );
-            std::transform(permutation.begin(), permutation.end(), sortedCoefficients.begin(), [&] (uint_fast64_t i) { return coefficients[i]; } );
+            // Finally, create the actual variable.
+            int error = 0;
+            error = GRBaddvar(model, 0, nullptr, nullptr, objectiveFunctionCoefficient, lowerBound, upperBound, variableType, name.c_str());
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Could not create binary Gurobi variable (" << GRBgeterrormsg(env) << ", error code " << error << ").");
+            this->variableNameToIndexMap.emplace(name, nextVariableIndex);
+            ++nextVariableIndex;
+        }
+                
+        void GurobiLpSolver::addConstraint(std::string const& name, storm::expressions::Expression const& constraint) {            
+            LOG_THROW(constraint.isRelationalExpression(), storm::exceptions::InvalidArgumentException, "Illegal constraint is not a relational expression.");
+            LOG_THROW(constraint.getOperator() != storm::expressions::OperatorType::NotEqual, storm::exceptions::InvalidArgumentException, "Illegal constraint uses inequality operator.");
             
-            // Now we perform the duplicate elimination step.
-            std::vector<int> uniqueVariables;
-            std::vector<double> uniqueCoefficients;
-			for (uint_fast64_t i = 0; i < sortedVariables.size(); ++i) {
-				if (!uniqueVariables.empty() && uniqueVariables.back() == sortedVariables[i]) {
-					uniqueCoefficients.back() += sortedCoefficients[i];
+            std::pair<storm::expressions::SimpleValuation, double> leftCoefficients = storm::expressions::LinearCoefficientVisitor().getLinearCoefficients(constraint.getOperand(0));
+            std::pair<storm::expressions::SimpleValuation, double> rightCoefficients = storm::expressions::LinearCoefficientVisitor().getLinearCoefficients(constraint.getOperand(1));
+            for (auto const& identifier : rightCoefficients.first.getDoubleIdentifiers()) {
+                if (leftCoefficients.first.containsDoubleIdentifier(identifier)) {
+                    leftCoefficients.first.setDoubleValue(identifier, leftCoefficients.first.getDoubleValue(identifier) - rightCoefficients.first.getDoubleValue(identifier));
                 } else {
-					uniqueVariables.push_back(static_cast<int>(sortedVariables[i]));
-					uniqueCoefficients.push_back(sortedCoefficients[i]);
+                    leftCoefficients.first.addDoubleIdentifier(identifier, -rightCoefficients.first.getDoubleValue(identifier));
                 }
             }
+            rightCoefficients.second -= leftCoefficients.second;
             
-            bool strictBound = boundType == LESS || boundType == GREATER;
-            char sense = boundType == LESS || boundType == LESS_EQUAL ? GRB_LESS_EQUAL : boundType == EQUAL ? GRB_EQUAL : GRB_GREATER_EQUAL;
-            
-            // If the constraint enforces a strict bound, we need to do some tweaking of the right-hand side value, because Gurobi only supports
-            // non-strict bounds.
-            if (strictBound) {
-                if (boundType == LESS) {
-                    rightHandSideValue -= storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble();
-                } else if (boundType == GREATER) {
-                    rightHandSideValue += storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble();
-                }
+            // Now we need to transform the coefficients to the vector representation.
+            std::vector<int> variables;
+            std::vector<double> coefficients;
+            for (auto const& identifier : leftCoefficients.first.getDoubleIdentifiers()) {
+                auto identifierIndexPair = this->variableNameToIndexMap.find(identifier);
+                LOG_THROW(identifierIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Constraint contains illegal identifier '" << identifier << "'.");
+                variables.push_back(identifierIndexPair->second);
+                coefficients.push_back(leftCoefficients.first.getDoubleValue(identifier));
             }
-            int error = GRBaddconstr(model, uniqueVariables.size(), uniqueVariables.data(), uniqueCoefficients.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
             
-            if (error) {
-                LOG4CPLUS_ERROR(logger, "Unable to assert Gurobi constraint (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to assert Gurobi constraint (" << GRBgeterrormsg(env) << ", error code " << error << ").";
+            // Determine the type of the constraint and add it properly.
+            int error = 0;
+            switch (constraint.getOperator()) {
+                case storm::expressions::OperatorType::Less:
+                    error = GRBaddconstr(model, variables.size(), variables.data(), coefficients.data(), GRB_LESS_EQUAL, rightCoefficients.second - storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble(), name == "" ? nullptr : name.c_str());
+                    break;
+                case storm::expressions::OperatorType::LessOrEqual:
+                    error = GRBaddconstr(model, variables.size(), variables.data(), coefficients.data(), GRB_LESS_EQUAL, rightCoefficients.second, name == "" ? nullptr : name.c_str());
+                    break;
+                case storm::expressions::OperatorType::Greater:
+                    error = GRBaddconstr(model, variables.size(), variables.data(), coefficients.data(), GRB_GREATER_EQUAL, rightCoefficients.second + storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble(), name == "" ? nullptr : name.c_str());
+                    break;
+                case storm::expressions::OperatorType::GreaterOrEqual:
+                    error = GRBaddconstr(model, variables.size(), variables.data(), coefficients.data(), GRB_GREATER_EQUAL, rightCoefficients.second, name == "" ? nullptr : name.c_str());
+                    break;
+                case storm::expressions::OperatorType::Equal:
+                    error = GRBaddconstr(model, variables.size(), variables.data(), coefficients.data(), GRB_EQUAL, rightCoefficients.second, name == "" ? nullptr : name.c_str());
+                    break;
+                default:
+                    LOG_ASSERT(false, "Illegal operator in LP solver constraint.");
             }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Could not assert constraint (" << GRBgeterrormsg(env) << ", error code " << error << ").");
         }
         
         void GurobiLpSolver::optimize() const {
@@ -212,18 +190,12 @@ namespace storm {
             this->update();
          
             // Set the most recently set model sense.
-            int error = GRBsetintattr(model, "ModelSense", this->getModelSense() == MINIMIZE ? 1 : -1);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to set Gurobi model sense (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi model sense (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            int error = GRBsetintattr(model, "ModelSense", this->getModelSense() == ModelSense::Minimize ? 1 : -1);
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi model sense (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             // Then we actually optimize the model.
             error = GRBoptimize(model);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to optimize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to optimize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to optimize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             this->currentModelHasBeenOptimized = true;
         }
@@ -236,34 +208,21 @@ namespace storm {
             int optimalityStatus = 0;
             
             int error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimalityStatus);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             // By default, Gurobi may tell us only that the model is either infeasible or unbounded. To decide which one
             // it is, we need to perform an extra step.
             if (optimalityStatus == GRB_INF_OR_UNBD) {
-                std::cout << "here" << std::endl;
                 error = GRBsetintparam(GRBgetenv(model), GRB_INT_PAR_DUALREDUCTIONS, 0);
-                if (error) {
-					LOG4CPLUS_ERROR(logger, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-					throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-                }
+                LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
                 
                 this->optimize();
                 
                 error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimalityStatus);
-                if (error) {
-					LOG4CPLUS_ERROR(logger, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-					throw storm::exceptions::InvalidStateException() << "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-                }
+                LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
                 
                 error = GRBsetintparam(GRBgetenv(model), GRB_INT_PAR_DUALREDUCTIONS, 1);
-                if (error) {
-					LOG4CPLUS_ERROR(logger, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-					throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-                }
+                LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             }
             
             return optimalityStatus == GRB_INFEASIBLE;
@@ -277,33 +236,21 @@ namespace storm {
             int optimalityStatus = 0;
             
             int error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimalityStatus);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             // By default, Gurobi may tell us only that the model is either infeasible or unbounded. To decide which one
             // it is, we need to perform an extra step.
             if (optimalityStatus == GRB_INF_OR_UNBD) {
                 error = GRBsetintparam(GRBgetenv(model), GRB_INT_PAR_DUALREDUCTIONS, 0);
-                if (error) {
-					LOG4CPLUS_ERROR(logger, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-					throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-                }
+                LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
                 
                 this->optimize();
 
                 error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimalityStatus);
-                if (error) {
-					LOG4CPLUS_ERROR(logger, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-					throw storm::exceptions::InvalidStateException() << "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-                }
+                LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
 
                 error = GRBsetintparam(GRBgetenv(model), GRB_INT_PAR_DUALREDUCTIONS, 1);
-                if (error) {
-					LOG4CPLUS_ERROR(logger, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-					throw storm::exceptions::InvalidStateException() << "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-                }
+                LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to set Gurobi parameter (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             }
             
             return optimalityStatus == GRB_UNBOUNDED;
@@ -316,120 +263,79 @@ namespace storm {
             int optimalityStatus = 0;
             
             int error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimalityStatus);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to retrieve optimization status of Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             return optimalityStatus == GRB_OPTIMAL;
         }
         
-        int_fast64_t GurobiLpSolver::getIntegerValue(uint_fast64_t variableIndex) const {
+        double GurobiLpSolver::getContinuousValue(std::string const& name) const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(!this->isUnbounded(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
             }
             
-            double value = 0;
-            int error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, variableIndex, &value);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            auto variableIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(variableIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidAccessException, "Accessing value of unknown variable '" << name << "'.");
             
-            if (std::abs(value - static_cast<int>(value)) <= storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble()) {
-                // Nothing to do in this case.
-            } else if (std::abs(value) > storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble()) {
-                LOG4CPLUS_ERROR(logger, "Illegal value for integer variable in Gurobi solution (" << value << ").");
-                throw storm::exceptions::InvalidStateException() << "Illegal value for integer variable in Gurobi solution (" << value << ").";
-            }
+            double value = 0;
+            int error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, variableIndexPair->second, &value);
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
-            return static_cast<int_fast64_t>(value);
+            return value;
         }
         
-        bool GurobiLpSolver::getBinaryValue(uint_fast64_t variableIndex) const {
+        int_fast64_t GurobiLpSolver::getIntegerValue(std::string const& name) const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").";
-                }
-            }
-
-            double value = 0;
-            int error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, variableIndex, &value);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").";
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(!this->isUnbounded(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
             }
             
-            if (std::abs(value - 1) <= storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble()) {
-                // Nothing to do in this case.
-            } else if (std::abs(value) > storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble()) {
-                LOG4CPLUS_ERROR(logger, "Illegal value for binary variable in Gurobi solution (" << value << ").");
-                throw storm::exceptions::InvalidStateException() << "Illegal value for binary variable in Gurobi solution (" << value << ").";
-            }
+            auto variableIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(variableIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidAccessException, "Accessing value of unknown variable '" << name << "'.");
             
-            return static_cast<bool>(value);
+            double value = 0;
+            int error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, variableIndexPair->second, &value);
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
+            LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for integer variable in Gurobi solution (" << value << ").");
+            
+            return static_cast<int_fast64_t>(value);
         }
         
-        double GurobiLpSolver::getContinuousValue(uint_fast64_t variableIndex) const {
+        bool GurobiLpSolver::getBinaryValue(std::string const& name) const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(!this->isUnbounded(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
             }
 
+            auto variableIndexPair = this->variableNameToIndexMap.find(name);
+            LOG_THROW(variableIndexPair != this->variableNameToIndexMap.end(), storm::exceptions::InvalidAccessException, "Accessing value of unknown variable '" << name << "'.");
+            
             double value = 0;
-            int error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, variableIndex, &value);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").";
+            int error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, variableIndexPair->second, &value);
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
+
+            if (value > 0.5) {
+                LOG_THROW(std::abs(static_cast<int>(value) - 1) <= storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for integer variable in Gurobi solution (" << value << ").");
+            } else {
+                LOG_THROW(value <= storm::settings::Settings::getInstance()->getOptionByLongName("gurobiinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for integer variable in Gurobi solution (" << value << ").");
             }
             
-            return value;
+            return static_cast<bool>(value);
         }
         
         double GurobiLpSolver::getObjectiveValue() const {
             if (!this->isOptimal()) {
-                if (this->isInfeasible()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").";
-                } else if (this->isUnbounded()) {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").";
-                } else {
-                    LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
-                    throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").";
-                }
+                LOG_THROW(!this->isInfeasible(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from infeasible model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(!this->isUnbounded(), storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unbounded model (" << GRBgeterrormsg(env) << ").");
+                LOG_THROW(false, storm::exceptions::InvalidAccessException, "Unable to get Gurobi solution from unoptimized model (" << GRBgeterrormsg(env) << ").");
             }
             
             double value = 0;
             int error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &value);
-            if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
-				throw storm::exceptions::InvalidStateException() << "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").";
-            }
+            LOG_THROW(error == 0, storm::exceptions::InvalidStateException, "Unable to get Gurobi solution (" << GRBgeterrormsg(env) << ", error code " << error << ").");
             
             return value;
         }
diff --git a/src/solver/GurobiLpSolver.h b/src/solver/GurobiLpSolver.h
index 27ac66c52..e9eac0e85 100644
--- a/src/solver/GurobiLpSolver.h
+++ b/src/solver/GurobiLpSolver.h
@@ -102,14 +102,28 @@ namespace storm {
              */
             void setGurobiEnvironmentProperties() const;
             
+            /*!
+             * Adds a variable with the given name, type, lower and upper bound and objective function coefficient.
+             *
+             * @param name The name of the variable.
+             * @param variableType The type of the variable in terms of Gurobi's constants.
+             * @param lowerBound The lower bound of the range of the variable.
+             * @param upperBound The upper bound of the range of the variable.
+             * @param objectiveFunctionCoefficient The coefficient of the variable in the objective function.
+             */
+            void addVariable(std::string const& name, char variableType, double lowerBound, double upperBound, double objectiveFunctionCoefficient);
+            
             // The Gurobi environment.
             GRBenv* env;
             
             // The Gurobi model.
             GRBmodel* model;
             
+            // The index of the next variable.
+            int nextVariableIndex;
+            
             // A mapping from variable names to their indices.
-            std::map<std::string, uint_fast64_t> variableNameToIndexMap;
+            std::map<std::string, int> variableNameToIndexMap;
         };
 #else
         // If Gurobi is not available, we provide a stub implementation that emits an error if any of its methods is called.
diff --git a/src/solver/LpSolver.h b/src/solver/LpSolver.h
index f775f2829..5e7a5f76e 100644
--- a/src/solver/LpSolver.h
+++ b/src/solver/LpSolver.h
@@ -16,14 +16,14 @@ namespace storm {
         public:
             // An enumeration to represent whether the objective function is to be minimized or maximized.
             enum class ModelSense {
-                MINIMIZE,
-                MAXIMIZE
+                Minimize,
+                Maximize
             };
             
             /*!
              * Creates an empty LP solver. By default the objective function is assumed to be minimized.
              */
-            LpSolver() : currentModelHasBeenOptimized(false), modelSense(ModelSense::MINIMIZE) {
+            LpSolver() : currentModelHasBeenOptimized(false), modelSense(ModelSense::Minimize) {
                 // Intentionally left empty.
             }
             
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 762ed07bf..e8de2af62 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -17,27 +17,27 @@ namespace storm {
         }
         
 		Expression Expression::substitute(std::map<std::string, Expression> const& identifierToExpressionMap) const {
-            return SubstitutionVisitor<std::map<std::string, Expression>>(identifierToExpressionMap).substitute(this);
+            return SubstitutionVisitor<std::map<std::string, Expression>>(identifierToExpressionMap).substitute(*this);
         }
 
 		Expression Expression::substitute(std::unordered_map<std::string, Expression> const& identifierToExpressionMap) const {
-			return SubstitutionVisitor<std::unordered_map<std::string, Expression>>(identifierToExpressionMap).substitute(this);
+			return SubstitutionVisitor<std::unordered_map<std::string, Expression>>(identifierToExpressionMap).substitute(*this);
 		}
         
 		Expression Expression::substitute(std::map<std::string, std::string> const& identifierToIdentifierMap) const {
-			return IdentifierSubstitutionVisitor<std::map<std::string, std::string>>(identifierToIdentifierMap).substitute(this);
+			return IdentifierSubstitutionVisitor<std::map<std::string, std::string>>(identifierToIdentifierMap).substitute(*this);
         }
 
 		Expression Expression::substitute(std::unordered_map<std::string, std::string> const& identifierToIdentifierMap) const {
-			return IdentifierSubstitutionVisitor<std::unordered_map<std::string, std::string>>(identifierToIdentifierMap).substitute(this);
+			return IdentifierSubstitutionVisitor<std::unordered_map<std::string, std::string>>(identifierToIdentifierMap).substitute(*this);
 		}
         
         void Expression::check(std::map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const {
-            return TypeCheckVisitor<std::map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this);
+            return TypeCheckVisitor<std::map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(*this);
         }
 
         void Expression::check(std::unordered_map<std::string, storm::expressions::ExpressionReturnType> const& identifierToTypeMap) const {
-            return TypeCheckVisitor<std::unordered_map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(this);
+            return TypeCheckVisitor<std::unordered_map<std::string, storm::expressions::ExpressionReturnType>>(identifierToTypeMap).check(*this);
         }
 
         bool Expression::evaluateAsBool(Valuation const* valuation) const {
diff --git a/src/storage/expressions/LinearCoefficientVisitor.cpp b/src/storage/expressions/LinearCoefficientVisitor.cpp
index f59804927..7525d6dde 100644
--- a/src/storage/expressions/LinearCoefficientVisitor.cpp
+++ b/src/storage/expressions/LinearCoefficientVisitor.cpp
@@ -28,7 +28,7 @@ namespace storm {
                 std::pair<SimpleValuation, double>& rightResult = resultStack.top();
                 
                 // Now add the left result to the right result.
-                for (auto const& identifier : leftResult.first.Valuation::getDoubleIdentifiers()) {
+                for (auto const& identifier : leftResult.first.getDoubleIdentifiers()) {
                     if (rightResult.first.containsDoubleIdentifier(identifier)) {
                         rightResult.first.setDoubleValue(identifier, leftResult.first.getDoubleValue(identifier) + rightResult.first.getDoubleValue(identifier));
                     } else {
@@ -52,7 +52,7 @@ namespace storm {
                         rightResult.first.setDoubleValue(identifier, leftResult.first.getDoubleValue(identifier));
                     }
                 }
-                for (auto const& identifier : rightResult.first.Valuation::getDoubleIdentifiers()) {
+                for (auto const& identifier : rightResult.first.getDoubleIdentifiers()) {
                     if (!leftResult.first.containsDoubleIdentifier(identifier)) {
                         rightResult.first.setDoubleValue(identifier, -rightResult.first.getDoubleValue(identifier));
                     }
diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
index baf39462f..f7ab3c985 100644
--- a/src/storage/expressions/Valuation.h
+++ b/src/storage/expressions/Valuation.h
@@ -94,7 +94,6 @@ namespace storm {
              */
             virtual std::set<std::string> getDoubleIdentifiers() const = 0;
 
-
         };
     }
 }
diff --git a/test/functional/solver/GlpkLpSolverTest.cpp b/test/functional/solver/GlpkLpSolverTest.cpp
index 30c3e10f9..a6410611d 100644
--- a/test/functional/solver/GlpkLpSolverTest.cpp
+++ b/test/functional/solver/GlpkLpSolverTest.cpp
@@ -3,34 +3,34 @@
 
 #include "src/solver/GlpkLpSolver.h"
 #include "src/exceptions/InvalidStateException.h"
+#include "src/exceptions/InvalidAccessException.h"
 #include "src/settings/Settings.h"
 
 TEST(GlpkLpSolver, LPOptimizeMax) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_NO_THROW(xValue = solver.getContinuousValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getContinuousValue("x"));
     ASSERT_LT(std::abs(xValue - 1), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getContinuousValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getContinuousValue("y"));
     ASSERT_LT(std::abs(yValue - 6.5), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 2.75), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -42,30 +42,29 @@ TEST(GlpkLpSolver, LPOptimizeMax) {
 
 TEST(GlpkLpSolver, LPOptimizeMin) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MINIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::BOUNDED, 1, 5.7, -1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Minimize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("z", 1, 5.7, -1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_NO_THROW(xValue = solver.getContinuousValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getContinuousValue("x"));
     ASSERT_LT(std::abs(xValue - 1), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getContinuousValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getContinuousValue("y"));
     ASSERT_LT(std::abs(yValue - 0), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 5.7), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -77,30 +76,29 @@ TEST(GlpkLpSolver, LPOptimizeMin) {
 
 TEST(GlpkLpSolver, MILPOptimizeMax) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createIntegerVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_NO_THROW(xValue = solver.getBinaryValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getBinaryValue("x"));
     ASSERT_EQ(true, xValue);
     int_fast64_t yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getIntegerValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getIntegerValue("y"));
     ASSERT_EQ(6, yValue);
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 3), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -112,30 +110,29 @@ TEST(GlpkLpSolver, MILPOptimizeMax) {
 
 TEST(GlpkLpSolver, MILPOptimizeMin) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MINIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createIntegerVariable("z", storm::solver::LpSolver::VariableType::BOUNDED, 0, 5, -1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Minimize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("z", 0, 5, -1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_NO_THROW(xValue = solver.getBinaryValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getBinaryValue("x"));
     ASSERT_EQ(true, xValue);
     int_fast64_t yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getIntegerValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getIntegerValue("y"));
     ASSERT_EQ(0, yValue);
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 5), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -147,31 +144,30 @@ TEST(GlpkLpSolver, MILPOptimizeMin) {
 
 TEST(GlpkLpSolver, LPInfeasible) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex}, {1}, storm::solver::LpSolver::BoundType::GREATER_EQUAL, 7));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") > storm::expressions::Expression::createDoubleLiteral(7)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_TRUE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_THROW(xValue = solver.getContinuousValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getContinuousValue("x"), storm::exceptions::InvalidAccessException);
     double yValue = 0;
-    ASSERT_THROW(yValue = solver.getContinuousValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getContinuousValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without glpk support.";
 #endif
@@ -179,31 +175,30 @@ TEST(GlpkLpSolver, LPInfeasible) {
 
 TEST(GlpkLpSolver, MILPInfeasible) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createIntegerVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex}, {1}, storm::solver::LpSolver::BoundType::GREATER_EQUAL, 7));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") > storm::expressions::Expression::createDoubleLiteral(7)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_TRUE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_THROW(xValue = solver.getBinaryValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getBinaryValue("x"), storm::exceptions::InvalidAccessException);
     int_fast64_t yValue = 0;
-    ASSERT_THROW(yValue = solver.getIntegerValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getIntegerValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without glpk support.";
 #endif
@@ -211,29 +206,28 @@ TEST(GlpkLpSolver, MILPInfeasible) {
 
 TEST(GlpkLpSolver, LPUnbounded) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_TRUE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_THROW(xValue = solver.getContinuousValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getContinuousValue("x"), storm::exceptions::InvalidAccessException);
     double yValue = 0;
-    ASSERT_THROW(yValue = solver.getContinuousValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getContinuousValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without glpk support.";
 #endif
@@ -241,30 +235,29 @@ TEST(GlpkLpSolver, LPUnbounded) {
 
 TEST(GlpkLpSolver, MILPUnbounded) {
 #ifdef STORM_HAVE_GLPK
-    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createIntegerVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
+    storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_TRUE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_THROW(xValue = solver.getBinaryValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getBinaryValue("x"), storm::exceptions::InvalidAccessException);
     int_fast64_t yValue = 0;
-    ASSERT_THROW(yValue = solver.getIntegerValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getIntegerValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without glpk support.";
 #endif
-}
\ No newline at end of file
+}
diff --git a/test/functional/solver/GurobiLpSolverTest.cpp b/test/functional/solver/GurobiLpSolverTest.cpp
index 1ca524d8e..ee0ebfa03 100644
--- a/test/functional/solver/GurobiLpSolverTest.cpp
+++ b/test/functional/solver/GurobiLpSolverTest.cpp
@@ -3,36 +3,34 @@
 
 #include "src/solver/GurobiLpSolver.h"
 #include "src/exceptions/InvalidStateException.h"
+#include "src/exceptions/InvalidAccessException.h"
 #include "src/settings/Settings.h"
 
 TEST(GurobiLpSolver, LPOptimizeMax) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-
-	ASSERT_NO_THROW(solver.update());
-
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
     
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
+
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_NO_THROW(xValue = solver.getContinuousValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getContinuousValue("x"));
     ASSERT_LT(std::abs(xValue - 1), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getContinuousValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getContinuousValue("y"));
     ASSERT_LT(std::abs(yValue - 6.5), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 2.75), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -44,32 +42,29 @@ TEST(GurobiLpSolver, LPOptimizeMax) {
 
 TEST(GurobiLpSolver, LPOptimizeMin) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MINIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::BOUNDED, 1, 5.7, -1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Minimize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("z", 1, 5.7, -1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_NO_THROW(xValue = solver.getContinuousValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getContinuousValue("x"));
     ASSERT_LT(std::abs(xValue - 1), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getContinuousValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getContinuousValue("y"));
     ASSERT_LT(std::abs(yValue - 0), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 5.7), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -81,32 +76,29 @@ TEST(GurobiLpSolver, LPOptimizeMin) {
 
 TEST(GurobiLpSolver, MILPOptimizeMax) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createIntegerVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_NO_THROW(xValue = solver.getBinaryValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getBinaryValue("x"));
     ASSERT_EQ(true, xValue);
     int_fast64_t yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getIntegerValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getIntegerValue("y"));
     ASSERT_EQ(6, yValue);
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 3), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -118,32 +110,29 @@ TEST(GurobiLpSolver, MILPOptimizeMax) {
 
 TEST(GurobiLpSolver, MILPOptimizeMin) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MINIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createIntegerVariable("z", storm::solver::LpSolver::VariableType::BOUNDED, 0, 5.7, -1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Minimize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("z", 0, 5, -1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_TRUE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_NO_THROW(xValue = solver.getBinaryValue(xIndex));
+    ASSERT_NO_THROW(xValue = solver.getBinaryValue("x"));
     ASSERT_EQ(true, xValue);
     int_fast64_t yValue = 0;
-    ASSERT_NO_THROW(yValue = solver.getIntegerValue(yIndex));
+    ASSERT_NO_THROW(yValue = solver.getIntegerValue("y"));
     ASSERT_EQ(0, yValue);
     double zValue = 0;
-    ASSERT_NO_THROW(zValue = solver.getContinuousValue(zIndex));
+    ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
     ASSERT_LT(std::abs(zValue - 5), storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble());
     double objectiveValue = 0;
     ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
@@ -155,33 +144,30 @@ TEST(GurobiLpSolver, MILPOptimizeMin) {
 
 TEST(GurobiLpSolver, LPInfeasible) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") > storm::expressions::Expression::createDoubleLiteral(7)));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex}, {1}, storm::solver::LpSolver::BoundType::GREATER_EQUAL, 7));
-    
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_TRUE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_THROW(xValue = solver.getContinuousValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getContinuousValue("x"), storm::exceptions::InvalidAccessException);
     double yValue = 0;
-    ASSERT_THROW(yValue = solver.getContinuousValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getContinuousValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without Gurobi support.";
 #endif
@@ -189,33 +175,30 @@ TEST(GurobiLpSolver, LPInfeasible) {
 
 TEST(GurobiLpSolver, MILPInfeasible) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createIntegerVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") > storm::expressions::Expression::createDoubleLiteral(7)));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, 1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, zIndex, xIndex}, {0.5, 1, -1}, storm::solver::LpSolver::BoundType::EQUAL, 5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex}, {1}, storm::solver::LpSolver::BoundType::GREATER_EQUAL, 7));
-    
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_FALSE(solver.isUnbounded());
     ASSERT_TRUE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_THROW(xValue = solver.getBinaryValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getBinaryValue("x"), storm::exceptions::InvalidAccessException);
     int_fast64_t yValue = 0;
-    ASSERT_THROW(yValue = solver.getIntegerValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getIntegerValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without Gurobi support.";
 #endif
@@ -223,31 +206,28 @@ TEST(GurobiLpSolver, MILPInfeasible) {
 
 TEST(GurobiLpSolver, LPUnbounded) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createContinuousVariable("x", storm::solver::LpSolver::VariableType::BOUNDED, 0, 1, -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createContinuousVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
+
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
-    
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_TRUE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     double xValue = 0;
-    ASSERT_THROW(xValue = solver.getContinuousValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getContinuousValue("x"), storm::exceptions::InvalidAccessException);
     double yValue = 0;
-    ASSERT_THROW(yValue = solver.getContinuousValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getContinuousValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without Gurobi support.";
 #endif
@@ -255,32 +235,28 @@ TEST(GurobiLpSolver, LPUnbounded) {
 
 TEST(GurobiLpSolver, MILPUnbounded) {
 #ifdef STORM_HAVE_GUROBI
-    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::MAXIMIZE);
-    uint_fast64_t xIndex;
-    ASSERT_NO_THROW(xIndex = solver.createBinaryVariable("x", -1));
-    uint_fast64_t yIndex;
-    ASSERT_NO_THROW(yIndex = solver.createIntegerVariable("y", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 2));
-    uint_fast64_t zIndex;
-    ASSERT_NO_THROW(zIndex = solver.createContinuousVariable("z", storm::solver::LpSolver::VariableType::LOWER_BOUND, 0, 0, 1));
-    
-	ASSERT_NO_THROW(solver.update());
+    storm::solver::GurobiLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
+    ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
+    ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
+    ASSERT_NO_THROW(solver.update());
 
-    ASSERT_NO_THROW(solver.addConstraint("", {xIndex, yIndex, zIndex}, {1, 1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 12));
-    ASSERT_NO_THROW(solver.addConstraint("", {yIndex, xIndex}, {1, -1}, storm::solver::LpSolver::BoundType::LESS_EQUAL, 5.5));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
+    ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
     
     ASSERT_NO_THROW(solver.optimize());
     ASSERT_FALSE(solver.isOptimal());
     ASSERT_TRUE(solver.isUnbounded());
     ASSERT_FALSE(solver.isInfeasible());
     bool xValue = false;
-    ASSERT_THROW(xValue = solver.getBinaryValue(xIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(xValue = solver.getBinaryValue("x"), storm::exceptions::InvalidAccessException);
     int_fast64_t yValue = 0;
-    ASSERT_THROW(yValue = solver.getIntegerValue(yIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(yValue = solver.getIntegerValue("y"), storm::exceptions::InvalidAccessException);
     double zValue = 0;
-    ASSERT_THROW(zValue = solver.getContinuousValue(zIndex), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
     double objectiveValue = 0;
-    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidStateException);
+    ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
 #else
     ASSERT_TRUE(false) << "StoRM built without Gurobi support.";
 #endif
-}
\ No newline at end of file
+}

From d80586b4aa4ae090c17dc42e3827d7d9f7745086 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 11 May 2014 20:39:41 +0200
Subject: [PATCH 118/147] Adapted MA model checker to new LP solver interface
 (LRA computation).

Former-commit-id: b23b72c8510ca956a9c80a80bf448a0a4289f630
---
 .../SparseMarkovAutomatonCslModelChecker.cpp  | 14 ++---
 .../SparseMarkovAutomatonCslModelChecker.h    | 52 +++++++++----------
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
index 580ea9c69..b5fa4bad4 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
@@ -1,8 +1,8 @@
-// #include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h"
+#include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h"
 
-//bool SparseMarkovAutomatonCslModelCheckerOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
-//    
-//	instance->addOption(storm::settings::OptionBuilder("GmmxxLinearEquationSolver", "digiprecision", "", "Precision used for iterative solving of linear equation systems").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("precision value", "Precision").setDefaultValueDouble(1e-4).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
-//    
-//	return true;
-//});
+bool SparseMarkovAutomatonCslModelCheckerOptionsRegistered = storm::settings::Settings::registerNewModule([] (storm::settings::Settings* instance) -> bool {
+    
+	instance->addOption(storm::settings::OptionBuilder("GmmxxLinearEquationSolver", "digiprecision", "", "Precision used for iterative solving of linear equation systems").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("precision value", "Precision").setDefaultValueDouble(1e-4).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
+    
+	return true;
+});
diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
index 8a924ba47..dbcf4d8b1 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
@@ -431,58 +431,58 @@ namespace storm {
                     solver->setModelSense(min ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
                     
                     // First, we need to create the variables for the problem.
-                    std::map<uint_fast64_t, uint_fast64_t> stateToVariableIndexMap;
+                    std::map<uint_fast64_t, std::string> stateToVariableNameMap;
                     for (auto const& stateChoicesPair : mec) {
-                        stateToVariableIndexMap[stateChoicesPair.first] = solver->createContinuousVariable("x" + std::to_string(stateChoicesPair.first), storm::solver::LpSolver::UNBOUNDED, 0, 0, 0);
+                        std::string variableName = "x" + std::to_string(stateChoicesPair.first);
+                        stateToVariableNameMap[stateChoicesPair.first] = variableName;
+                        solver->addUnboundedContinuousVariable(variableName);
                     }
-                    uint_fast64_t lraValueVariableIndex = solver->createContinuousVariable("k", storm::solver::LpSolver::UNBOUNDED, 0, 0, 1);
+                    solver->addUnboundedContinuousVariable("k", 1);
                     solver->update();
                     
                     // Now we encode the problem as constraints.
-                    std::vector<uint_fast64_t> variables;
-                    std::vector<double> coefficients;
                     for (auto const& stateChoicesPair : mec) {
                         uint_fast64_t state = stateChoicesPair.first;
                         
                         // Now, based on the type of the state, create a suitable constraint.
                         if (markovianStates.get(state)) {
-                            variables.clear();
-                            coefficients.clear();
-                            
-                            variables.push_back(stateToVariableIndexMap.at(state));
-                            coefficients.push_back(1);
+                            storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(state));
                             
                             for (auto element : transitionMatrix.getRow(nondeterministicChoiceIndices[state])) {
-                                variables.push_back(stateToVariableIndexMap.at(element.getColumn()));
-                                coefficients.push_back(-element.getValue());
+                                constraint = constraint - storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(element.getColumn()));
                             }
                             
-                            variables.push_back(lraValueVariableIndex);
-                            coefficients.push_back(storm::utility::constantOne<ValueType>() / exitRates[state]);
-                            
-                            solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, goalStates.get(state) ? storm::utility::constantOne<ValueType>() / exitRates[state] : storm::utility::constantZero<ValueType>());
+                            constraint = constraint + storm::expressions::Expression::createDoubleLiteral(storm::utility::constantOne<ValueType>() / exitRates[state]) * storm::expressions::Expression::createDoubleVariable("k");
+                            storm::expressions::Expression rightHandSide = goalStates.get(state) ? storm::expressions::Expression::createDoubleLiteral(storm::utility::constantOne<ValueType>() / exitRates[state]) : storm::expressions::Expression::createDoubleLiteral(storm::utility::constantZero<ValueType>());
+                            if (min) {
+                                constraint = constraint <= rightHandSide;
+                            } else {
+                                constraint = constraint >= rightHandSide;
+                            }
+                            solver->addConstraint("state" + std::to_string(state), constraint);
                         } else {
                             // For probabilistic states, we want to add the constraint x_s <= sum P(s, a, s') * x_s' where a is the current action
                             // and the sum ranges over all states s'.
                             for (auto choice : stateChoicesPair.second) {
-                                variables.clear();
-                                coefficients.clear();
-                                
-                                variables.push_back(stateToVariableIndexMap.at(state));
-                                coefficients.push_back(1);
-                                
+                                storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(state));
+
                                 for (auto element : transitionMatrix.getRow(choice)) {
-                                    variables.push_back(stateToVariableIndexMap.at(element.getColumn()));
-                                    coefficients.push_back(-element.getValue());
+                                    constraint = constraint - storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(element.getColumn()));
                                 }
                                 
-                                solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, storm::utility::constantZero<ValueType>());
+                                storm::expressions::Expression rightHandSide = storm::expressions::Expression::createDoubleLiteral(storm::utility::constantZero<ValueType>());
+                                if (min) {
+                                    constraint = constraint <= rightHandSide;
+                                } else {
+                                    constraint = constraint >= rightHandSide;
+                                }
+                                solver->addConstraint("state" + std::to_string(state), constraint);
                             }
                         }
                     }
                     
                     solver->optimize();
-                    return solver->getContinuousValue(lraValueVariableIndex);
+                    return solver->getContinuousValue("k");
                 }
                 
                 /*!

From db4721ce3ab1aff53bdb3928e7eccdf862ec2db9 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 11 May 2014 22:30:50 +0200
Subject: [PATCH 119/147] Started adapting MILP-based counterexample generator
 to new LP solver interface.

Former-commit-id: b571d744db9a94e90cf85263ca9d8e5a3b6f132e
---
 .../MILPMinimalLabelSetGenerator.h            | 151 +++++++++---------
 1 file changed, 77 insertions(+), 74 deletions(-)

diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index 4e0f9381c..8da1374c4 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -65,13 +65,13 @@ namespace storm {
              * A helper struct capturing information about the variables of the MILP formulation.
              */
             struct VariableInformation {
-                std::unordered_map<uint_fast64_t, uint_fast64_t> labelToVariableIndexMap;
-                std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> stateToChoiceVariablesIndexMap;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> initialStateToChoiceVariableIndexMap;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> stateToProbabilityVariableIndexMap;
-                uint_fast64_t virtualInitialStateVariableIndex;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> problematicStateToVariableIndexMap;
-                std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash> problematicTransitionToVariableIndexMap;
+                std::unordered_map<uint_fast64_t, std::string> labelToVariableMap;
+                std::unordered_map<uint_fast64_t, std::list<std::string>> stateToChoiceVariablesMap;
+                std::unordered_map<uint_fast64_t, std::string> initialStateToChoiceVariableMap;
+                std::unordered_map<uint_fast64_t, std::string> stateToProbabilityVariableMap;
+                std::string virtualInitialStateVariable;
+                std::unordered_map<uint_fast64_t, std::string> problematicStateToVariableMap;
+                std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash> problematicTransitionToVariableMap;
                 uint_fast64_t numberOfVariables;
 
 				VariableInformation() : numberOfVariables(0) {}
@@ -167,14 +167,15 @@ namespace storm {
              * @param relevantLabels The set of relevant labels of the model.
              * @return A mapping from labels to variable indices.
              */
-            static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createLabelVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
+            static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createLabelVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
                 std::stringstream variableNameBuffer;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
+                std::unordered_map<uint_fast64_t, std::string> resultingMap;
                 for (auto const& label : relevantLabels) {
                     variableNameBuffer.str("");
                     variableNameBuffer.clear();
                     variableNameBuffer << "label" << label;
-                    resultingMap[label] = solver.createBinaryVariable(variableNameBuffer.str(), 1);
+                    resultingMap[label] = variableNameBuffer.str();
+                    solver.addBinaryVariable(resultingMap[label], 1);
                 }
                 return std::make_pair(resultingMap, relevantLabels.size());
             }
@@ -187,10 +188,10 @@ namespace storm {
              * @param choiceInformation The information about the choices of the model.
              * @return A mapping from states to a list of choice variable indices.
              */
-            static std::pair<std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>>, uint_fast64_t> createSchedulerVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
+            static std::pair<std::unordered_map<uint_fast64_t, std::list<std::string>>, uint_fast64_t> createSchedulerVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
-                std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> resultingMap;
+                std::unordered_map<uint_fast64_t, std::list<std::string>> resultingMap;
                 
                 for (auto state : stateInformation.relevantStates) {
                     resultingMap.emplace(state, std::list<uint_fast64_t>());
@@ -199,7 +200,8 @@ namespace storm {
                         variableNameBuffer.str("");
                         variableNameBuffer.clear();
                         variableNameBuffer << "choice" << row << "in" << state;
-                        resultingMap[state].push_back(solver.createBinaryVariable(variableNameBuffer.str(), 0));
+                        resultingMap[state].push_back(variableNameBuffer.str());
+                        solver.addBinaryVariable(resultingMap[state].back());
                         ++numberOfVariablesCreated;
                     }
                 }
@@ -215,10 +217,10 @@ namespace storm {
              * @param stateInformation The information about the states of the model.
              * @return A mapping from initial states to choice variable indices.
              */
-            static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation) {
+            static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation) {
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
+                std::unordered_map<uint_fast64_t, std::string> resultingMap;
                 
                 for (auto initialState : labeledMdp.getLabeledStates("init")) {
                     // Only consider this initial state if it is relevant.
@@ -226,7 +228,8 @@ namespace storm {
                         variableNameBuffer.str("");
                         variableNameBuffer.clear();
                         variableNameBuffer << "init" << initialState;
-                        resultingMap[initialState] = solver.createBinaryVariable(variableNameBuffer.str(), 0);
+                        resultingMap[initialState] = variableNameBuffer.str();
+                        solver.addBinaryVariable(resultingMap[initialState]);
                         ++numberOfVariablesCreated;
                     }
                 }
@@ -240,16 +243,17 @@ namespace storm {
              * @param stateInformation The information about the states in the model.
              * @return A mapping from states to the index of the corresponding probability variables.
              */
-            static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createProbabilityVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation) {
+            static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createProbabilityVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation) {
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
+                std::unordered_map<uint_fast64_t, std::string> resultingMap;
                 
                 for (auto state : stateInformation.relevantStates) {
                     variableNameBuffer.str("");
                     variableNameBuffer.clear();
                     variableNameBuffer << "p" << state;
-                    resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
+                    resultingMap[state] = variableNameBuffer.str();
+                    solver.addBoundedContinuousVariable(resultingMap[state], 0, 1);
                     ++numberOfVariablesCreated;
                 }
                 return std::make_pair(resultingMap, numberOfVariablesCreated);
@@ -263,11 +267,12 @@ namespace storm {
              * label-minimal subsystem of maximal probability is computed.
              * @return The index of the variable for the probability of the virtual initial state.
              */
-            static std::pair<uint_fast64_t, uint_fast64_t> createVirtualInitialStateVariable(storm::solver::LpSolver& solver, bool maximizeProbability = false) {
+            static std::pair<std::string, uint_fast64_t> createVirtualInitialStateVariable(storm::solver::LpSolver& solver, bool maximizeProbability = false) {
                 std::stringstream variableNameBuffer;
                 variableNameBuffer << "pinit";
-                
-                return std::make_pair(solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0), 1);
+                std::string variableName = variableNameBuffer.str();
+                solver.addBoundedContinuousVariable(variableName, 0, 1);
+                return std::make_pair(variableName, 1);
             }
             
             /*!
@@ -278,10 +283,10 @@ namespace storm {
              * @param stateInformation The information about the states in the model.
              * @return A mapping from problematic states to the index of the corresponding variables.
              */
-            static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
+            static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
-                std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
+                std::unordered_map<uint_fast64_t, std::string> resultingMap;
                 
                 for (auto state : stateInformation.problematicStates) {
                     // First check whether there is not already a variable for this state and advance to the next state
@@ -290,7 +295,8 @@ namespace storm {
                         variableNameBuffer.str("");
                         variableNameBuffer.clear();
                         variableNameBuffer << "r" << state;
-                        resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
+                        resultingMap[state] = variableNameBuffer.str();
+                        solver.addBoundedContinuousVariable(resultingMap[state], 0, 1);
                         ++numberOfVariablesCreated;
                     }
                     
@@ -302,7 +308,8 @@ namespace storm {
                                     variableNameBuffer.str("");
                                     variableNameBuffer.clear();
                                     variableNameBuffer << "r" << successorEntry.getColumn();
-                                    resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
+                                    resultingMap[state] = variableNameBuffer.str();
+                                    solver.addBoundedContinuousVariable(resultingMap[state], 0, 1);
                                     ++numberOfVariablesCreated;
                                 }
                             }
@@ -321,10 +328,10 @@ namespace storm {
              * @param choiceInformation The information about the choices in the model.
              * @return A mapping from problematic choices to the index of the corresponding variables.
              */
-            static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
+            static std::pair<std::unordered_map<std::pair<uint_fast64_t, std::string>, uint_fast64_t, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
-                std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash> resultingMap;
+                std::unordered_map<std::pair<uint_fast64_t, std::string>, uint_fast64_t, PairHash> resultingMap;
                 
                 for (auto state : stateInformation.problematicStates) {
                     std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
@@ -334,7 +341,8 @@ namespace storm {
                                 variableNameBuffer.str("");
                                 variableNameBuffer.clear();
                                 variableNameBuffer << "t" << state << "to" << successorEntry.getColumn();
-                                resultingMap[std::make_pair(state, successorEntry.getColumn())] = solver.createBinaryVariable(variableNameBuffer.str(), 0);
+                                resultingMap[std::make_pair(state, successorEntry.getColumn())] = variableNameBuffer.str();
+                                solver.addBinaryVariable(resultingMap[std::make_pair(state, successorEntry.getColumn())]);
                                 ++numberOfVariablesCreated;
                             }
                         }
@@ -382,7 +390,7 @@ namespace storm {
                 LOG4CPLUS_DEBUG(logger, "Created variables for the reachability probabilities.");
 
                 // Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state.
-                std::pair<uint_fast64_t, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
+                std::pair<std::string, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
                 result.virtualInitialStateVariableIndex = virtualInitialStateVariableResult.first;
                 result.numberOfVariables += virtualInitialStateVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for the virtual initial state.");
@@ -419,7 +427,13 @@ namespace storm {
              * @return The total number of constraints that were created.
              */
             static uint_fast64_t assertProbabilityGreaterThanThreshold(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound) {
-                solver.addConstraint("ProbGreaterThreshold", {variableInformation.virtualInitialStateVariableIndex}, {1}, strictBound ? storm::solver::LpSolver::GREATER : storm::solver::LpSolver::GREATER_EQUAL, probabilityThreshold);
+                storm::expressions::Expression constraint;
+                if (strictBound) {
+                    constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) > storm::expressions::Expression::createDoubleLiteral(probabilityThreshold);
+                } else {
+                    constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) >= storm::expressions::Expression::createDoubleLiteral(probabilityThreshold);
+                }
+                solver.addConstraint("ProbGreaterThreshold", constraint);
                 return 1;
             }
             
@@ -435,28 +449,28 @@ namespace storm {
                 // Assert that the policy chooses at most one action in each state of the system.
                 uint_fast64_t numberOfConstraintsCreated = 0;
                 for (auto state : stateInformation.relevantStates) {
-                    std::list<uint_fast64_t> const& choiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(state);
-                    std::vector<uint_fast64_t> variables;
-                    std::vector<double> coefficients(choiceVariableIndices.size(), 1);
-                    variables.reserve(choiceVariableIndices.size());
-                    for (auto choiceVariableIndex : choiceVariableIndices) {
-                        variables.push_back(choiceVariableIndex);
+                    std::list<std::string> const& choiceVariableIndices = variableInformation.stateToChoiceVariablesMap.at(state);
+                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
+
+                    for (auto const& choiceVariable : choiceVariableIndices) {
+                        constraint = constraint + storm::expressions::Expression::createDoubleVariable(choiceVariable);
                     }
                     
-                    solver.addConstraint("ValidPolicy" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 1);
+                    constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
+                    
+                    solver.addConstraint("ValidPolicy" + std::to_string(numberOfConstraintsCreated), constraint);
                     ++numberOfConstraintsCreated;
                 }
                 
                 // Now assert that the virtual initial state picks exactly one initial state from the system as its
                 // successor state.
-                std::vector<uint_fast64_t> variables;
-                variables.reserve(variableInformation.initialStateToChoiceVariableIndexMap.size());
-                std::vector<double> coefficients(variableInformation.initialStateToChoiceVariableIndexMap.size(), 1);
-                for (auto initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
-                    variables.push_back(initialStateVariableIndexPair.second);
+                storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
+                for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
+                    constraint = constraint + storm::expressions::Expression::createDoubleVariable(initialStateVariablePair.second);
                 }
+                constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
                 
-                solver.addConstraint("VirtualInitialStateChoosesOneInitialState", variables, coefficients, storm::solver::LpSolver::EQUAL, 1);
+                solver.addConstraint("VirtualInitialStateChoosesOneInitialState", constraint);
                 ++numberOfConstraintsCreated;
                 
                 return numberOfConstraintsCreated;
@@ -478,13 +492,14 @@ namespace storm {
 
                 std::vector<boost::container::flat_set<uint_fast64_t>> const& choiceLabeling = labeledMdp.getChoiceLabeling();
                 for (auto state : stateInformation.relevantStates) {
-                    std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
+                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
                     for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
                         for (auto label : choiceLabeling[choice]) {
-                            solver.addConstraint("ChoicesImplyLabels" + std::to_string(numberOfConstraintsCreated), {variableInformation.labelToVariableIndexMap.at(label), *choiceVariableIndicesIterator}, {1, -1}, storm::solver::LpSolver::GREATER_EQUAL, 0);
+                            storm::expressions::Expression constraint = storm::expressions::Expression::createIntegerVariable(variableInformation.labelToVariableMap.at(label)) - storm::expressions::Expression::createIntegerVariable(*choiceVariableIterator) >= storm::expressions::Expression::createDoubleLiteral(0);
+                            solver.addConstraint("ChoicesImplyLabels" + std::to_string(numberOfConstraintsCreated), constraint);
                             ++numberOfConstraintsCreated;
                         }
-                        ++choiceVariableIndicesIterator;
+                        ++choiceVariableIterator;
                     }
                 }
                 return numberOfConstraintsCreated;
@@ -503,16 +518,12 @@ namespace storm {
             static uint_fast64_t assertZeroProbabilityWithoutChoice(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
                 uint_fast64_t numberOfConstraintsCreated = 0;
                 for (auto state : stateInformation.relevantStates) {
-                    std::list<uint_fast64_t> const& choiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(state);
-
-                    std::vector<double> coefficients(choiceVariableIndices.size() + 1, -1);
-                    coefficients[0] = 1;
-                    std::vector<uint_fast64_t> variables;
-                    variables.reserve(variableInformation.stateToChoiceVariablesIndexMap.at(state).size() + 1);
-                    variables.push_back(variableInformation.stateToProbabilityVariableIndexMap.at(state));
-                    variables.insert(variables.end(), choiceVariableIndices.begin(), choiceVariableIndices.end());
-                    
-                    solver.addConstraint("ProbabilityIsZeroIfNoAction" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 0);
+                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(state));
+                    for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(state)) {
+                        constraint = constraint - storm::expressions::Expression::createDoubleVariable(choiceVariable);
+                    }
+                    constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
+                    solver.addConstraint("ProbabilityIsZeroIfNoAction" + std::to_string(numberOfConstraintsCreated), constraint);
                     ++numberOfConstraintsCreated;
                 }
                 return numberOfConstraintsCreated;
@@ -532,40 +543,32 @@ namespace storm {
             static uint_fast64_t assertReachabilityProbabilities(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
                 uint_fast64_t numberOfConstraintsCreated = 0;
                 for (auto state : stateInformation.relevantStates) {
-                    std::vector<double> coefficients;
-                    std::vector<uint_fast64_t> variables;
-                    
-                    std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
+                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
                     for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
-                        variables.clear();
-                        coefficients.clear();
-                        variables.push_back(variableInformation.stateToProbabilityVariableIndexMap.at(state));
-                        coefficients.push_back(1.0);
+                        storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(state));
                         
                         double rightHandSide = 1;
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
                             if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
-                                variables.push_back(static_cast<int>(variableInformation.stateToProbabilityVariableIndexMap.at(successorEntry.getColumn())));
-                                coefficients.push_back(-successorEntry.getValue());
+                                constraint = constraint - storm::expressions::Expression::createDoubleLiteral(successorEntry.getValue()) * storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(successorEntry.getColumn()));
                             } else if (psiStates.get(successorEntry.getColumn())) {
                                 rightHandSide += successorEntry.getValue();
                             }
                         }
                         
-                        coefficients.push_back(1);
-                        variables.push_back(*choiceVariableIndicesIterator);
-                        
-                        solver.addConstraint("ReachabilityProbabilities" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, rightHandSide);
+                        constraint = constraint + storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator) <= storm::expressions::Expression::createDoubleLiteral(rightHandSide);
+                        solver.addConstraint("ReachabilityProbabilities" + std::to_string(numberOfConstraintsCreated), constraint);
                         
                         ++numberOfConstraintsCreated;
-                        ++choiceVariableIndicesIterator;
+                        ++choiceVariableIterator;
                     }
                 }
                 
                 // Make sure that the virtual initial state is being assigned the probability from the initial state
                 // that it selected as a successor state.
-                for (auto initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
-                    solver.addConstraint("VirtualInitialStateHasCorrectProbability" + std::to_string(numberOfConstraintsCreated), {variableInformation.virtualInitialStateVariableIndex, variableInformation.stateToProbabilityVariableIndexMap.at(initialStateVariableIndexPair.first), initialStateVariableIndexPair.second}, {1, -1, 1}, storm::solver::LpSolver::LESS_EQUAL, 1);
+                for (auto const& initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
+                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) - storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(initialStateVariableIndexPair.first)) + storm::expressions::Expression::createDoubleVariable(initialStateVariableIndexPair.second) <= storm::expressions::Expression::createDoubleLiteral(1);
+                    solver.addConstraint("VirtualInitialStateHasCorrectProbability" + std::to_string(numberOfConstraintsCreated), constraint);
                     ++numberOfConstraintsCreated;
                 }
                 

From 9e746549a8a90923c99e1089ea550021bcf5f92e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 12 May 2014 11:41:07 +0200
Subject: [PATCH 120/147] Fully adapted MILP-based counterexample generator to
 new LP solver interface.

Former-commit-id: 83f3b8c5075c5c614671b82ceb6cf6c762e3592c
---
 .../MILPMinimalLabelSetGenerator.h            | 182 ++++++++----------
 src/solver/GlpkLpSolver.h                     |   4 +-
 src/solver/GurobiLpSolver.h                   |   4 +-
 src/solver/LpSolver.h                         |   2 +-
 4 files changed, 87 insertions(+), 105 deletions(-)

diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index 8da1374c4..ad581e616 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -194,7 +194,7 @@ namespace storm {
                 std::unordered_map<uint_fast64_t, std::list<std::string>> resultingMap;
                 
                 for (auto state : stateInformation.relevantStates) {
-                    resultingMap.emplace(state, std::list<uint_fast64_t>());
+                    resultingMap.emplace(state, std::list<std::string>());
                     std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
                     for (uint_fast64_t row : relevantChoicesForState) {
                         variableNameBuffer.str("");
@@ -260,7 +260,7 @@ namespace storm {
             }
             
             /*!
-             * Creates the variables for the probabilities in the model.
+             * Creates the variable for the probability of the virtual initial state.
              *
              * @param solver The MILP solver.
              * @param maximizeProbability If set to true, the objective function is constructed in a way that a
@@ -308,8 +308,8 @@ namespace storm {
                                     variableNameBuffer.str("");
                                     variableNameBuffer.clear();
                                     variableNameBuffer << "r" << successorEntry.getColumn();
-                                    resultingMap[state] = variableNameBuffer.str();
-                                    solver.addBoundedContinuousVariable(resultingMap[state], 0, 1);
+                                    resultingMap[successorEntry.getColumn()] = variableNameBuffer.str();
+                                    solver.addBoundedContinuousVariable(resultingMap[successorEntry.getColumn()], 0, 1);
                                     ++numberOfVariablesCreated;
                                 }
                             }
@@ -328,10 +328,10 @@ namespace storm {
              * @param choiceInformation The information about the choices in the model.
              * @return A mapping from problematic choices to the index of the corresponding variables.
              */
-            static std::pair<std::unordered_map<std::pair<uint_fast64_t, std::string>, uint_fast64_t, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
+            static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
                 std::stringstream variableNameBuffer;
                 uint_fast64_t numberOfVariablesCreated = 0;
-                std::unordered_map<std::pair<uint_fast64_t, std::string>, uint_fast64_t, PairHash> resultingMap;
+                std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash> resultingMap;
                 
                 for (auto state : stateInformation.problematicStates) {
                     std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
@@ -366,44 +366,44 @@ namespace storm {
                 VariableInformation result;
                 
                 // Create variables for involved labels.
-                std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
-                result.labelToVariableIndexMap = std::move(labelVariableResult.first);
+                std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
+                result.labelToVariableMap = std::move(labelVariableResult.first);
                 result.numberOfVariables += labelVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for labels.");
                 
                 // Create scheduler variables for relevant states and their actions.
-                std::pair<std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
-                result.stateToChoiceVariablesIndexMap = std::move(schedulerVariableResult.first);
+                std::pair<std::unordered_map<uint_fast64_t, std::list<std::string>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
+                result.stateToChoiceVariablesMap = std::move(schedulerVariableResult.first);
                 result.numberOfVariables += schedulerVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for nondeterministic choices.");
 
                 // Create scheduler variables for nondeterministically choosing an initial state.
-                std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
-                result.initialStateToChoiceVariableIndexMap = std::move(initialChoiceVariableResult.first);
+                std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
+                result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first);
                 result.numberOfVariables += initialChoiceVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for the nondeterministic choice of the initial state.");
                 
                 // Create variables for probabilities for all relevant states.
-                std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation);
-                result.stateToProbabilityVariableIndexMap = std::move(probabilityVariableResult.first);
+                std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation);
+                result.stateToProbabilityVariableMap = std::move(probabilityVariableResult.first);
                 result.numberOfVariables += probabilityVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for the reachability probabilities.");
 
                 // Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state.
                 std::pair<std::string, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
-                result.virtualInitialStateVariableIndex = virtualInitialStateVariableResult.first;
+                result.virtualInitialStateVariable = virtualInitialStateVariableResult.first;
                 result.numberOfVariables += virtualInitialStateVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for the virtual initial state.");
 
                 // Create variables for problematic states.
-                std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
-                result.problematicStateToVariableIndexMap = std::move(problematicStateVariableResult.first);
+                std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
+                result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first);
                 result.numberOfVariables += problematicStateVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for the problematic states.");
 
                 // Create variables for problematic choices.
-                std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
-                result.problematicTransitionToVariableIndexMap = problematicTransitionVariableResult.first;
+                std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
+                result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first;
                 result.numberOfVariables += problematicTransitionVariableResult.second;
                 LOG4CPLUS_DEBUG(logger, "Created variables for the problematic choices.");
 
@@ -453,7 +453,7 @@ namespace storm {
                     storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
 
                     for (auto const& choiceVariable : choiceVariableIndices) {
-                        constraint = constraint + storm::expressions::Expression::createDoubleVariable(choiceVariable);
+                        constraint = constraint + storm::expressions::Expression::createIntegerVariable(choiceVariable);
                     }
                     
                     constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
@@ -466,9 +466,9 @@ namespace storm {
                 // successor state.
                 storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
                 for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
-                    constraint = constraint + storm::expressions::Expression::createDoubleVariable(initialStateVariablePair.second);
+                    constraint = constraint + storm::expressions::Expression::createIntegerVariable(initialStateVariablePair.second);
                 }
-                constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
+                constraint = constraint == storm::expressions::Expression::createDoubleLiteral(1);
                 
                 solver.addConstraint("VirtualInitialStateChoosesOneInitialState", constraint);
                 ++numberOfConstraintsCreated;
@@ -492,7 +492,7 @@ namespace storm {
 
                 std::vector<boost::container::flat_set<uint_fast64_t>> const& choiceLabeling = labeledMdp.getChoiceLabeling();
                 for (auto state : stateInformation.relevantStates) {
-                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
+                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
                     for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
                         for (auto label : choiceLabeling[choice]) {
                             storm::expressions::Expression constraint = storm::expressions::Expression::createIntegerVariable(variableInformation.labelToVariableMap.at(label)) - storm::expressions::Expression::createIntegerVariable(*choiceVariableIterator) >= storm::expressions::Expression::createDoubleLiteral(0);
@@ -520,7 +520,7 @@ namespace storm {
                 for (auto state : stateInformation.relevantStates) {
                     storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(state));
                     for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(state)) {
-                        constraint = constraint - storm::expressions::Expression::createDoubleVariable(choiceVariable);
+                        constraint = constraint - storm::expressions::Expression::createIntegerVariable(choiceVariable);
                     }
                     constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
                     solver.addConstraint("ProbabilityIsZeroIfNoAction" + std::to_string(numberOfConstraintsCreated), constraint);
@@ -556,7 +556,7 @@ namespace storm {
                             }
                         }
                         
-                        constraint = constraint + storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator) <= storm::expressions::Expression::createDoubleLiteral(rightHandSide);
+                        constraint = constraint + storm::expressions::Expression::createIntegerVariable(*choiceVariableIterator) <= storm::expressions::Expression::createDoubleLiteral(rightHandSide);
                         solver.addConstraint("ReachabilityProbabilities" + std::to_string(numberOfConstraintsCreated), constraint);
                         
                         ++numberOfConstraintsCreated;
@@ -566,8 +566,8 @@ namespace storm {
                 
                 // Make sure that the virtual initial state is being assigned the probability from the initial state
                 // that it selected as a successor state.
-                for (auto const& initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
-                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) - storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(initialStateVariableIndexPair.first)) + storm::expressions::Expression::createDoubleVariable(initialStateVariableIndexPair.second) <= storm::expressions::Expression::createDoubleLiteral(1);
+                for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
+                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) - storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(initialStateVariablePair.first)) + storm::expressions::Expression::createDoubleVariable(initialStateVariablePair.second) <= storm::expressions::Expression::createDoubleLiteral(1);
                     solver.addConstraint("VirtualInitialStateHasCorrectProbability" + std::to_string(numberOfConstraintsCreated), constraint);
                     ++numberOfConstraintsCreated;
                 }
@@ -590,44 +590,34 @@ namespace storm {
 
                 for (auto stateListPair : choiceInformation.problematicChoicesForProblematicStates) {
                     for (auto problematicChoice : stateListPair.second) {
-                        std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(stateListPair.first).begin();
+                        std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(stateListPair.first).begin();
                         for (auto relevantChoice : choiceInformation.relevantChoicesForRelevantStates.at(stateListPair.first)) {
                             if (relevantChoice == problematicChoice) {
                                 break;
                             }
-                            ++choiceVariableIndicesIterator;
+                            ++choiceVariableIterator;
                         }
                         
-                        std::vector<uint_fast64_t> variables;
-                        std::vector<double> coefficients;
-                        
-                        variables.push_back(*choiceVariableIndicesIterator);
-                        coefficients.push_back(1);
-                        
+                        storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
-                            variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(stateListPair.first, successorEntry.getColumn())));
-                            coefficients.push_back(-1);
+                            constraint = constraint - storm::expressions::Expression::createDoubleVariable(variableInformation.problematicTransitionToVariableMap.at(std::make_pair(stateListPair.first, successorEntry.getColumn())));
                         }
+                        constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
                         
-                        solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 0);
+                        solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), constraint);
                         ++numberOfConstraintsCreated;
                     }
                 }
                 
                 for (auto state : stateInformation.problematicStates) {
                     for (auto problematicChoice : choiceInformation.problematicChoicesForProblematicStates.at(state)) {
-                        for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(state)) {
-                            std::vector<uint_fast64_t> variables;
-                            std::vector<double> coefficients;
-                            
-                            variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(state));
-                            coefficients.push_back(1);
-                            variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(successorEntry.getColumn()));
-                            coefficients.push_back(-1);
-                            variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(state, successorEntry.getColumn())));
-                            coefficients.push_back(1);
+                        for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
+                            storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.problematicStateToVariableMap.at(state));
+                            constraint = constraint - storm::expressions::Expression::createDoubleVariable(variableInformation.problematicStateToVariableMap.at(successorEntry.getColumn()));
+                            constraint = constraint + storm::expressions::Expression::createDoubleVariable(variableInformation.problematicTransitionToVariableMap.at(std::make_pair(state, successorEntry.getColumn())));
+                            constraint = constraint < storm::expressions::Expression::createDoubleLiteral(1);
                             
-                            solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS, 1);
+                            solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), constraint);
                             ++numberOfConstraintsCreated;
                         }
                     }
@@ -649,7 +639,8 @@ namespace storm {
                 uint_fast64_t numberOfConstraintsCreated = 0;
 
                 for (auto label : choiceInformation.knownLabels) {
-                    solver.addConstraint("KnownLabels" + std::to_string(numberOfConstraintsCreated), {variableInformation.labelToVariableIndexMap.at(label)}, {1}, storm::solver::LpSolver::EQUAL, 1);
+                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.labelToVariableMap.at(label)) == storm::expressions::Expression::createDoubleLiteral(1);
+                    solver.addConstraint("KnownLabels" + std::to_string(numberOfConstraintsCreated), constraint);
                     ++numberOfConstraintsCreated;
                 }
 
@@ -670,13 +661,11 @@ namespace storm {
             static uint_fast64_t assertSchedulerCuts(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
                 storm::storage::SparseMatrix<T> backwardTransitions = labeledMdp.getBackwardTransitions();
                 uint_fast64_t numberOfConstraintsCreated = 0;
-                std::vector<uint_fast64_t> variables;
-                std::vector<double> coefficients;
                 
                 for (auto state : stateInformation.relevantStates) {
                     // Assert that all states, that select an action, this action either has a non-zero probability to
                     // go to a psi state directly, or in the successor states, at least one action is selected as well.
-                    std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
+                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
                     for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
                         bool psiStateReachableInOneStep = false;
                         for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
@@ -686,38 +675,31 @@ namespace storm {
                         }
                         
                         if (!psiStateReachableInOneStep) {
-                            variables.clear();
-                            coefficients.clear();
-                            
-                            variables.push_back(static_cast<int>(*choiceVariableIndicesIterator));
-                            coefficients.push_back(1);
-                            
+                            storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
                             for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
                                 if (state != successorEntry.getColumn() && stateInformation.relevantStates.get(successorEntry.getColumn())) {
-                                    std::list<uint_fast64_t> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(successorEntry.getColumn());
+                                    std::list<std::string> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesMap.at(successorEntry.getColumn());
                                     
-                                    for (auto choiceVariableIndex : successorChoiceVariableIndices) {
-                                        variables.push_back(choiceVariableIndex);
-                                        coefficients.push_back(-1);
+                                    for (auto const& choiceVariable : successorChoiceVariableIndices) {
+                                        constraint = constraint - storm::expressions::Expression::createDoubleVariable(choiceVariable);
                                     }
                                 }
                             }
+                            constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
                             
-                            solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 1);
+                            solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
                             ++numberOfConstraintsCreated;
                         }
                         
-                        ++choiceVariableIndicesIterator;
+                        ++choiceVariableIterator;
                     }
                     
                     // For all states assert that there is either a selected incoming transition in the subsystem or the
                     // state is the chosen initial state if there is one selected action in the current state.
-                    variables.clear();
-                    coefficients.clear();
-                    
-                    for (auto choiceVariableIndex : variableInformation.stateToChoiceVariablesIndexMap.at(state)) {
-                        variables.push_back(choiceVariableIndex);
-                        coefficients.push_back(1);
+                    storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
+
+                    for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(state)) {
+                        constraint = constraint + storm::expressions::Expression::createDoubleVariable(choiceVariable);
                     }
                     
                     // Compute the set of predecessors.
@@ -734,7 +716,7 @@ namespace storm {
                             continue;
                         }
                         
-                        std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(predecessor).begin();
+                        std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(predecessor).begin();
                         for (auto relevantChoice : choiceInformation.relevantChoicesForRelevantStates.at(predecessor)) {
                             bool choiceTargetsCurrentState = false;
                             
@@ -748,39 +730,36 @@ namespace storm {
                             
                             // If it does, we can add the choice to the sum.
                             if (choiceTargetsCurrentState) {
-                                variables.push_back(static_cast<int>(*choiceVariableIndicesIterator));
-                                coefficients.push_back(-1);
+                                constraint = constraint - storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
                             }
-                            ++choiceVariableIndicesIterator;
+                            ++choiceVariableIterator;
                         }
                     }
                     
                     // If the current state is an initial state and is selected as a successor state by the virtual
                     // initial state, then this also justifies making a choice in the current state.
                     if (labeledMdp.getLabeledStates("init").get(state)) {
-                        variables.push_back(variableInformation.initialStateToChoiceVariableIndexMap.at(state));
-                        coefficients.push_back(-1);
+                        constraint = constraint - storm::expressions::Expression::createDoubleVariable(variableInformation.initialStateToChoiceVariableMap.at(state));
                     }
+                    constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
                     
-                    solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 0);
+                    solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
                     ++numberOfConstraintsCreated;
                 }
                 
                 // Assert that at least one initial state selects at least one action.
-                variables.clear();
-                coefficients.clear();
+                storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
                 for (auto initialState : labeledMdp.getLabeledStates("init")) {
-                    for (auto choiceVariableIndex : variableInformation.stateToChoiceVariablesIndexMap.at(initialState)) {
-                        variables.push_back(choiceVariableIndex);
-                        coefficients.push_back(1);
+                    for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(initialState)) {
+                        constraint = constraint + storm::expressions::Expression::createDoubleVariable(choiceVariable);
                     }
                 }
-                solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::GREATER_EQUAL, 1);
+                constraint = constraint >= storm::expressions::Expression::createDoubleLiteral(1);
+                solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
                 ++numberOfConstraintsCreated;
                 
                 // Add constraints that ensure at least one choice is selected that targets a psi state.
-                variables.clear();
-                coefficients.clear();
+                constraint = storm::expressions::Expression::createDoubleLiteral(0);
                 std::unordered_set<uint_fast64_t> predecessors;
                 for (auto psiState : psiStates) {
                     // Compute the set of predecessors.
@@ -797,7 +776,7 @@ namespace storm {
                         continue;
                     }
                     
-                    std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(predecessor).begin();
+                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(predecessor).begin();
                     for (auto relevantChoice : choiceInformation.relevantChoicesForRelevantStates.at(predecessor)) {
                         bool choiceTargetsPsiState = false;
                         
@@ -811,14 +790,14 @@ namespace storm {
                         
                         // If it does, we can add the choice to the sum.
                         if (choiceTargetsPsiState) {
-                            variables.push_back(*choiceVariableIndicesIterator);
-                            coefficients.push_back(1);
+                            constraint = constraint + storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
                         }
-                        ++choiceVariableIndicesIterator;
+                        ++choiceVariableIterator;
                     }
                 }
+                constraint = constraint >= storm::expressions::Expression::createDoubleLiteral(1);
                 
-                solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::GREATER_EQUAL, 1);
+                solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
                 ++numberOfConstraintsCreated;
                 
                 return numberOfConstraintsCreated;
@@ -875,6 +854,9 @@ namespace storm {
                     LOG4CPLUS_DEBUG(logger, "Asserted scheduler cuts.");
                 }
                 
+                // Finally, we can tell the solver to incorporate the latest changes.
+                solver.update();
+                
                 LOG4CPLUS_INFO(logger, "Successfully created " << numberOfConstraints << " MILP constraints.");
             }
             
@@ -887,7 +869,7 @@ namespace storm {
             static boost::container::flat_set<uint_fast64_t> getUsedLabelsInSolution(storm::solver::LpSolver const& solver, VariableInformation const& variableInformation) {
                 boost::container::flat_set<uint_fast64_t> result;
 
-                for (auto labelVariablePair : variableInformation.labelToVariableIndexMap) {
+                for (auto const& labelVariablePair : variableInformation.labelToVariableMap) {
                     bool labelTaken = solver.getBinaryValue(labelVariablePair.second);
                     
                     if (labelTaken) {
@@ -911,10 +893,10 @@ namespace storm {
                 std::map<uint_fast64_t, uint_fast64_t> result;
                 
                 for (auto state : stateInformation.relevantStates) {
-                    std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
+                    std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
                     for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
-                        bool choiceTaken = solver.getBinaryValue(*choiceVariableIndicesIterator);
-                        ++choiceVariableIndicesIterator;
+                        bool choiceTaken = solver.getBinaryValue(*choiceVariableIterator);
+                        ++choiceVariableIterator;
                         if (choiceTaken) {
                             result.emplace_hint(result.end(), state, choice);
                         }
@@ -933,20 +915,20 @@ namespace storm {
              */
             static std::pair<uint_fast64_t, double> getReachabilityProbability(storm::solver::LpSolver const& solver, storm::models::Mdp<T> const& labeledMdp, VariableInformation const& variableInformation) {
                 uint_fast64_t selectedInitialState = 0;
-                for (auto initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
-                    bool initialStateChosen = solver.getBinaryValue(initialStateVariableIndexPair.second);
+                for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
+                    bool initialStateChosen = solver.getBinaryValue(initialStateVariablePair.second);
                     if (initialStateChosen) {
-                        selectedInitialState = initialStateVariableIndexPair.first;
+                        selectedInitialState = initialStateVariablePair.first;
                         break;
                     }
                 }
                 
-                double reachabilityProbability = solver.getContinuousValue(variableInformation.virtualInitialStateVariableIndex);
+                double reachabilityProbability = solver.getContinuousValue(variableInformation.virtualInitialStateVariable);
                 return std::make_pair(selectedInitialState, reachabilityProbability);
             }
                 
         public:
-            
+
             static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, bool checkThresholdFeasible = false, bool includeSchedulerCuts = false) {
                 // (0) Check whether the MDP is indeed labeled.
                 if (!labeledMdp.hasChoiceLabeling()) {
diff --git a/src/solver/GlpkLpSolver.h b/src/solver/GlpkLpSolver.h
index 1f6d7bd2a..0931e1ca5 100644
--- a/src/solver/GlpkLpSolver.h
+++ b/src/solver/GlpkLpSolver.h
@@ -68,7 +68,7 @@ namespace storm {
             virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
 
             // Methods to add binary variables.
-            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override;
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
 
             // Methods to incorporate recent changes.
             virtual void update() const override;
@@ -184,7 +184,7 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override {
+            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
diff --git a/src/solver/GurobiLpSolver.h b/src/solver/GurobiLpSolver.h
index e9eac0e85..90bef47eb 100644
--- a/src/solver/GurobiLpSolver.h
+++ b/src/solver/GurobiLpSolver.h
@@ -73,7 +73,7 @@ namespace storm {
             virtual void addUnboundedIntegerVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
             
             // Methods to add binary variables.
-            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override;
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override;
             
             // Methods to incorporate recent changes.
             virtual void update() const override;
@@ -176,7 +176,7 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) override {
+            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
diff --git a/src/solver/LpSolver.h b/src/solver/LpSolver.h
index 5e7a5f76e..8c729a323 100644
--- a/src/solver/LpSolver.h
+++ b/src/solver/LpSolver.h
@@ -130,7 +130,7 @@ namespace storm {
              * @param objectiveFunctionCoefficient The coefficient with which the variable appears in the objective
              * function. If omitted (or set to zero), the variable is irrelevant for the objective value.
              */
-            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient) = 0;
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) = 0;
             
             /*!
              * Updates the model to make the variables that have been declared since the last call to <code>update</code>

From 686618e6e2d5174ae7f8d634dfd0bc648e0c3ad0 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 12 May 2014 21:57:52 +0200
Subject: [PATCH 121/147] Added missing header to (hopefully) fix MSVC
 problems.

Former-commit-id: 0247ce1e355226573ff04c44f6512aa6c690192f
---
 src/storage/expressions/Valuation.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/storage/expressions/Valuation.h b/src/storage/expressions/Valuation.h
index f7ab3c985..a09c4f07c 100644
--- a/src/storage/expressions/Valuation.h
+++ b/src/storage/expressions/Valuation.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_VALUATION_H_
 
 #include <string>
+#include <set>
 
 namespace storm {
     namespace expressions {

From 66d6fa3bb4ab896e1903149251333e24ad8ee02c Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 15 May 2014 17:34:55 +0200
Subject: [PATCH 122/147] Fixed wrong type.

Former-commit-id: 59e08c3669c6a5f71110830da43966ec1c302e24
---
 src/solver/GlpkLpSolver.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/solver/GlpkLpSolver.h b/src/solver/GlpkLpSolver.h
index 0931e1ca5..85a0847af 100644
--- a/src/solver/GlpkLpSolver.h
+++ b/src/solver/GlpkLpSolver.h
@@ -184,7 +184,7 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             
-            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for glpk. Yet, a method was called that requires this support. Please choose a version of support with glpk support.";
             }
             

From 45486600f7255b13c5b96b878d49d026df73a2ef Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 15 May 2014 20:35:33 +0200
Subject: [PATCH 123/147] Made parts of the interface of the DdManager
 protected (because they shouldn't be accessible from the outside world).

Former-commit-id: bf52a653b83e3cfe4990c43f438fac533791d6f0
---
 src/storage/dd/CuddDdManager.cpp       | 105 +++++++------------------
 src/storage/dd/CuddDdManager.h         |  34 +++-----
 test/functional/storage/CuddDdTest.cpp |  40 +++-------
 3 files changed, 48 insertions(+), 131 deletions(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 087382c71..fd26a782c 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -3,6 +3,7 @@
 #include <algorithm>
 
 #include "src/storage/dd/CuddDdManager.h"
+#include "src/exceptions/ExceptionMacros.h"
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/settings/Settings.h"
 
@@ -49,17 +50,9 @@ namespace storm {
         }
         
         Dd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
-            // Check whether the meta variable exists.
-            if (!this->hasMetaVariable(metaVariableName)) {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
-            }
-            
             DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
-            // Check whether the value is legal for this meta variable.
-            if (value < metaVariable.getLow() || value > metaVariable.getHigh()) {
-                throw storm::exceptions::InvalidArgumentException() << "Illegal value " << value << " for meta variable '" << metaVariableName << "'.";
-            }
+            LOG_THROW(value >= metaVariable.getLow() && value <= metaVariable.getHigh(), storm::exceptions::InvalidArgumentException, "Illegal value " << value << " for meta variable '" << metaVariableName << "'.");
             
             // Now compute the encoding relative to the low value of the meta variable.
             value -= metaVariable.getLow();
@@ -85,11 +78,6 @@ namespace storm {
         }
         
         Dd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(std::string const& metaVariableName) {
-            // Check whether the meta variable exists.
-            if (!this->hasMetaVariable(metaVariableName)) {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
-            }
-
             storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
             Dd<DdType::CUDD> result = this->getZero();
@@ -101,11 +89,6 @@ namespace storm {
         }
         
         Dd<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(std::string const& metaVariableName) {
-            // Check whether the meta variable exists.
-            if (!this->hasMetaVariable(metaVariableName)) {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
-            }
-            
             storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
             
             Dd<DdType::CUDD> result = this->getZero();
@@ -116,91 +99,57 @@ namespace storm {
         }
 
         void DdManager<DdType::CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
+            // Check whether the variable name is legal.
+            LOG_THROW(name != "" && name.back() != '\'', storm::exceptions::InvalidArgumentException, "Illegal name of meta variable: '" << name << "'.");
+            
             // Check whether a meta variable already exists.
-            if (this->hasMetaVariable(name)) {
-                throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
-            }
+            LOG_THROW(!this->hasMetaVariable(name), storm::exceptions::InvalidArgumentException, "A meta variable '" << name << "' already exists.");
 
             // Check that the range is legal.
-            if (high == low) {
-                throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements.";
-            }
+            LOG_THROW(high != low, storm::exceptions::InvalidArgumentException, "Range of meta variable must be at least 2 elements.");
             
             std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
             
             std::vector<Dd<DdType::CUDD>> variables;
+            std::vector<Dd<DdType::CUDD>> variablesPrime;
             for (std::size_t i = 0; i < numberOfBits; ++i) {
                 variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
+                variablesPrime.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name + "'"}));
+            }
+            
+            // Now group the non-primed and primed variable.
+            for (uint_fast64_t i = 0; i < numberOfBits; ++i) {
+                this->getCuddManager().MakeTreeNode(variables[i].getCuddAdd().NodeReadIndex(), 2, MTR_FIXED);
             }
             
             metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, low, high, variables, this->shared_from_this()));
+            metaVariableMap.emplace(name + "'", DdMetaVariable<DdType::CUDD>(name + "'", low, high, variablesPrime, this->shared_from_this()));
         }
         
         void DdManager<DdType::CUDD>::addMetaVariable(std::string const& name) {
+            // Check whether the variable name is legal.
+            LOG_THROW(name != "" && name.back() != '\'', storm::exceptions::InvalidArgumentException, "Illegal name of meta variable: '" << name << "'.");
+            
             // Check whether a meta variable already exists.
-            if (this->hasMetaVariable(name)) {
-                throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
-            }
+            LOG_THROW(!this->hasMetaVariable(name), storm::exceptions::InvalidArgumentException, "A meta variable '" << name << "' already exists.");
             
             std::vector<Dd<DdType::CUDD>> variables;
+            std::vector<Dd<DdType::CUDD>> variablesPrime;
             variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
-            
-            metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, variables, this->shared_from_this()));
-        }
-        
-        void DdManager<DdType::CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high, bool fixedGroup) {
-            // Make sure that at least one meta variable is added.
-            if (names.size() == 0) {
-                throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables.";
-            }
-            
-            // Check that there are no duplicate names in the given name vector.
-            std::vector<std::string> nameCopy(names);
-            std::sort(nameCopy.begin(), nameCopy.end());
-            if (std::adjacent_find(nameCopy.begin(), nameCopy.end()) != nameCopy.end()) {
-                throw storm::exceptions::InvalidArgumentException() << "Cannot add duplicate meta variables.";
-            }
-            
-            // Check that the range is legal.
-            if (high == low) {
-                throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements.";
-            }
+            variablesPrime.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name + "'"}));
 
-            // Check whether a meta variable already exists.
-            for (auto const& metaVariableName : names) {
-                if (this->hasMetaVariable(metaVariableName)) {
-                    throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << metaVariableName << "' already exists.";
-                }
-            }
-            
-            // Add the variables in interleaved order.
-            std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
-            std::vector<std::vector<Dd<DdType::CUDD>>> variables(names.size());
-            for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
-                for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                    variables[i].emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
-                }
-            }
-            
-            // If required, we group the bits on the same layer of the interleaved meta variables.
-            if (fixedGroup) {
-                for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                    this->getCuddManager().MakeTreeNode(variables[i].front().getCuddAdd().NodeReadIndex(), names.size(), MTR_FIXED);
-                }
-            }
+            // Now group the non-primed and primed variable.
+            this->getCuddManager().MakeTreeNode(variables.front().getCuddAdd().NodeReadIndex(), 2, MTR_FIXED);
             
-            // Now add the meta variables.
-            for (uint_fast64_t i = 0; i < names.size(); ++i) {
-                metaVariableMap.emplace(names[i], DdMetaVariable<DdType::CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
-            }
+            metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, variables, this->shared_from_this()));
+            metaVariableMap.emplace(name + "'", DdMetaVariable<DdType::CUDD>(name + "'", variablesPrime, this->shared_from_this()));
         }
         
         DdMetaVariable<DdType::CUDD> const& DdManager<DdType::CUDD>::getMetaVariable(std::string const& metaVariableName) const {
             auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
             
-            if (!this->hasMetaVariable(metaVariableName)) {
-                throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
-            }
+            // Check whether the meta variable exists.
+            LOG_THROW(nameVariablePair != metaVariableMap.end(), storm::exceptions::InvalidArgumentException, "Unknown meta variable name '" << metaVariableName << "'.");
             
             return nameVariablePair->second;
         }
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 6fba4d254..a4607a57c 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -16,6 +16,7 @@ namespace storm {
         class DdManager<DdType::CUDD> : public std::enable_shared_from_this<DdManager<DdType::CUDD>> {
         public:
             friend class Dd<DdType::CUDD>;
+            friend class DdForwardIterator<DdType::CUDD>;
             
             /*!
              * Creates an empty manager without any meta variables.
@@ -83,7 +84,7 @@ namespace storm {
             /*!
              * Adds an integer meta variable with the given name and range.
              *
-             * @param name The name of the meta variable.
+             * @param name The (non-empty) name of the meta variable.
              * @param low The lowest value of the range of the variable.
              * @param high The highest value of the range of the variable.
              */
@@ -92,30 +93,10 @@ namespace storm {
             /*!
              * Adds a boolean meta variable with the given name.
              *
-             * @param name The name of the meta variable.
+             * @param name The (non-empty) name of the meta variable.
              */
             void addMetaVariable(std::string const& name);
             
-            /*!
-             * Adds integer meta variables with the given names and (equal) range and arranges the DD variables in an
-             * interleaved order.
-             *
-             * @param names The names of the variables.
-             * @param low The lowest value of the ranges of the variables.
-             * @param high The highest value of the ranges of the variables.
-             * @param fixedGroup If set to true, the interleaved bits of the meta variable are always kept together as
-             * a group during a potential reordering.
-             */
-            void addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high, bool fixedGroup = true);
-            
-            /*!
-             * Retrieves the meta variable with the given name if it exists.
-             *
-             * @param metaVariableName The name of the meta variable to retrieve.
-             * @return The meta variable with the given name.
-             */
-            DdMetaVariable<DdType::CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
-            
             /*!
              * Retrieves the names of all meta variables that have been added to the manager.
              *
@@ -157,6 +138,15 @@ namespace storm {
              */
             void triggerReordering();
             
+        protected:
+            /*!
+             * Retrieves the meta variable with the given name if it exists.
+             *
+             * @param metaVariableName The name of the meta variable to retrieve.
+             * @return The meta variable with the given name.
+             */
+            DdMetaVariable<DdType::CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
+            
         private:
             /*!
              * Retrieves a list of names of the DD variables in the order of their index.
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index ce40c94d1..f39e4ad48 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -38,26 +38,18 @@ TEST(CuddDdManager, Constants) {
 TEST(CuddDdManager, AddGetMetaVariableTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
-    EXPECT_EQ(1, manager->getNumberOfMetaVariables());
+    EXPECT_EQ(2, manager->getNumberOfMetaVariables());
     
-    std::vector<std::string> names = {"x", "x'"};
-    ASSERT_THROW(manager->addMetaVariablesInterleaved(names, 0, 3), storm::exceptions::InvalidArgumentException);
+    ASSERT_THROW(manager->addMetaVariable("x", 0, 3), storm::exceptions::InvalidArgumentException);
 
-    names = {"y", "y"};
-    ASSERT_THROW(manager->addMetaVariablesInterleaved(names, 0, 3), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(manager->addMetaVariable("y", 0, 3));
+    EXPECT_EQ(4, manager->getNumberOfMetaVariables());
     
-    names = {"y", "y'"};
-    ASSERT_NO_THROW(manager->addMetaVariablesInterleaved(names, 0, 3));
-    EXPECT_EQ(3, manager->getNumberOfMetaVariables());
-    
-    EXPECT_FALSE(manager->hasMetaVariable("x'"));
+    EXPECT_TRUE(manager->hasMetaVariable("x'"));
     EXPECT_TRUE(manager->hasMetaVariable("y'"));
     
-    std::set<std::string> metaVariableSet = {"x", "y", "y'"};
+    std::set<std::string> metaVariableSet = {"x", "x'", "y", "y'"};
     EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames());
-    
-    ASSERT_THROW(storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x'"), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
 }
 
 TEST(CuddDdManager, EncodingTest) {
@@ -99,20 +91,6 @@ TEST(CuddDdManager, IdentityTest) {
     EXPECT_EQ(21, range.getNodeCount());
 }
 
-TEST(CuddDdMetaVariable, AccessorTest) {
-    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
-    manager->addMetaVariable("x", 1, 9);
-    EXPECT_EQ(1, manager->getNumberOfMetaVariables());
-    ASSERT_NO_THROW(storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x"));
-    storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariableX = manager->getMetaVariable("x");
-    
-    EXPECT_EQ(1, metaVariableX.getLow());
-    EXPECT_EQ(9, metaVariableX.getHigh());
-    EXPECT_EQ("x", metaVariableX.getName());
-    EXPECT_EQ(manager, metaVariableX.getDdManager());
-    EXPECT_EQ(4, metaVariableX.getNumberOfDdVariables());
-}
-
 TEST(CuddDd, OperatorTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     manager->addMetaVariable("x", 1, 9);
@@ -200,7 +178,7 @@ TEST(CuddDd, OperatorTest) {
 
 TEST(CuddDd, AbstractionTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
-    manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+    manager->addMetaVariable("x", 1, 9);
     storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
     storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
     storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
@@ -246,7 +224,7 @@ TEST(CuddDd, AbstractionTest) {
 TEST(CuddDd, SwapTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
     
-    manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+    manager->addMetaVariable("x", 1, 9);
     manager->addMetaVariable("z", 2, 8);
     storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
     storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
@@ -259,7 +237,7 @@ TEST(CuddDd, SwapTest) {
 
 TEST(CuddDd, MultiplyMatrixTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
-    manager->addMetaVariablesInterleaved({"x", "x'"}, 1, 9);
+    manager->addMetaVariable("x", 1, 9);
     
     storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getIdentity("x").equals(manager->getIdentity("x'"));
     storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getRange("x'");

From 6a2d75d68dbbd97991d64a4acf7b516b36d337a4 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 15 May 2014 21:34:23 +0200
Subject: [PATCH 124/147] Some changes in anticipation of integrating MEDDLY.

Former-commit-id: 0f7a71ec9bdfaa979ab071dbf0ba60dbab8d9b83
---
 src/storage/dd/CuddDdManager.h        |   2 +-
 src/storage/dd/CuddDdMetaVariable.cpp |  52 ++++++++++
 src/storage/dd/CuddDdMetaVariable.h   | 138 ++++++++++++++++++++++++++
 src/storage/dd/DdMetaVariable.cpp     |  65 ------------
 src/storage/dd/DdMetaVariable.h       | 136 ++-----------------------
 5 files changed, 197 insertions(+), 196 deletions(-)
 create mode 100644 src/storage/dd/CuddDdMetaVariable.cpp
 create mode 100644 src/storage/dd/CuddDdMetaVariable.h
 delete mode 100644 src/storage/dd/DdMetaVariable.cpp

diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index a4607a57c..14ea4d8a3 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -4,7 +4,7 @@
 #include <unordered_map>
 
 #include "src/storage/dd/DdManager.h"
-#include "src/storage/dd/DdMetaVariable.h"
+#include "src/storage/dd/CuddDdMetaVariable.h"
 #include "src/utility/OsDetection.h"
 
 // Include the C++-interface of CUDD.
diff --git a/src/storage/dd/CuddDdMetaVariable.cpp b/src/storage/dd/CuddDdMetaVariable.cpp
new file mode 100644
index 000000000..b7f45dbe3
--- /dev/null
+++ b/src/storage/dd/CuddDdMetaVariable.cpp
@@ -0,0 +1,52 @@
+#include "src/storage/dd/CuddDdMetaVariable.h"
+#include "src/storage/dd/CuddDdManager.h"
+
+namespace storm {
+    namespace dd {
+        DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Int), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
+            // Create the cube of all variables of this meta variable.
+            for (auto const& ddVariable : this->ddVariables) {
+                this->cube *= ddVariable;
+            }
+        }
+        
+        DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Bool), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
+            // Create the cube of all variables of this meta variable.
+            for (auto const& ddVariable : this->ddVariables) {
+                this->cube *= ddVariable;
+            }
+        }
+        
+        std::string const& DdMetaVariable<DdType::CUDD>::getName() const {
+            return this->name;
+        }
+        
+        typename DdMetaVariable<DdType::CUDD>::MetaVariableType DdMetaVariable<DdType::CUDD>::getType() const {
+            return this->type;
+        }
+        
+        int_fast64_t DdMetaVariable<DdType::CUDD>::getLow() const {
+            return this->low;
+        }
+
+        int_fast64_t DdMetaVariable<DdType::CUDD>::getHigh() const {
+            return this->high;
+        }
+        
+        std::size_t DdMetaVariable<DdType::CUDD>::getNumberOfDdVariables() const {
+            return this->ddVariables.size();
+        }
+        
+        std::shared_ptr<DdManager<DdType::CUDD>> DdMetaVariable<DdType::CUDD>::getDdManager() const {
+            return this->manager;
+        }
+
+        std::vector<Dd<DdType::CUDD>> const& DdMetaVariable<DdType::CUDD>::getDdVariables() const {
+            return this->ddVariables;
+        }
+        
+        Dd<DdType::CUDD> const& DdMetaVariable<DdType::CUDD>::getCube() const {
+            return this->cube;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdMetaVariable.h b/src/storage/dd/CuddDdMetaVariable.h
new file mode 100644
index 000000000..b54ca1939
--- /dev/null
+++ b/src/storage/dd/CuddDdMetaVariable.h
@@ -0,0 +1,138 @@
+#ifndef STORM_STORAGE_DD_DDMETAVARIABLE_H_
+#define STORM_STORAGE_DD_DDMETAVARIABLE_H_
+
+#include <memory>
+#include <vector>
+#include <cstdint>
+#include <string>
+
+#include "utility/OsDetection.h"
+#include "src/storage/dd/CuddDd.h"
+#include "src/storage/dd/DdMetaVariable.h"
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace dd {
+        // Forward-declare the DdManager class.
+        template<DdType Type> class DdManager;
+        
+        template<>
+        class DdMetaVariable<DdType::CUDD> {
+        public:
+            // Declare the DdManager class as friend so it can access the internals of a meta variable.
+            friend class DdManager<DdType::CUDD>;
+            friend class Dd<DdType::CUDD>;
+            friend class DdForwardIterator<DdType::CUDD>;
+            
+            // An enumeration for all legal types of meta variables.
+            enum class MetaVariableType { Bool, Int };
+            
+            /*!
+             * Creates an integer meta variable with the given name and range bounds.
+             *
+             * @param name The name of the meta variable.
+             * @param low The lowest value of the range of the variable.
+             * @param high The highest value of the range of the variable.
+             * @param ddVariables The vector of variables used to encode this variable.
+             * @param manager A pointer to the manager that is responsible for this meta variable.
+             */
+            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager);
+            
+            /*!
+             * Creates a boolean meta variable with the given name.
+             * @param name The name of the meta variable.
+             * @param ddVariables The vector of variables used to encode this variable.
+             * @param manager A pointer to the manager that is responsible for this meta variable.
+             */
+            DdMetaVariable(std::string const& name, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager);
+            
+            // Explictly generate all default versions of copy/move constructors/assignments.
+            DdMetaVariable(DdMetaVariable const& other) = default;
+			DdMetaVariable& operator=(DdMetaVariable const& other) = default;
+#ifndef WINDOWS
+            DdMetaVariable(DdMetaVariable&& other) = default;
+            DdMetaVariable& operator=(DdMetaVariable&& other) = default;
+#endif
+            
+            /*!
+             * Retrieves the name of the meta variable.
+             *
+             * @return The name of the variable.
+             */
+            std::string const& getName() const;
+            
+            /*!
+             * Retrieves the type of the meta variable.
+             *
+             * @return The type of the meta variable.
+             */
+            MetaVariableType getType() const;
+            
+            /*!
+             * Retrieves the lowest value of the range of the variable.
+             *
+             * @return The lowest value of the range of the variable.
+             */
+            int_fast64_t getLow() const;
+            
+            /*!
+             * Retrieves the highest value of the range of the variable.
+             *
+             * @return The highest value of the range of the variable.
+             */
+            int_fast64_t getHigh() const;
+            
+            /*!
+             * Retrieves the manager that is responsible for this meta variable.
+             *
+             * A pointer to the manager that is responsible for this meta variable.
+             */
+            std::shared_ptr<DdManager<DdType::CUDD>> getDdManager() const;
+            
+            /*!
+             * Retrieves the number of DD variables for this meta variable.
+             *
+             * @return The number of DD variables for this meta variable.
+             */
+            std::size_t getNumberOfDdVariables() const;
+            
+        private:
+            /*!
+             * Retrieves the variables used to encode the meta variable.
+             *
+             * @return A vector of variables used to encode the meta variable.
+             */
+            std::vector<Dd<DdType::CUDD>> const& getDdVariables() const;
+            
+            /*!
+             * Retrieves the cube of all variables that encode this meta variable.
+             *
+             * @return The cube of all variables that encode this meta variable.
+             */
+            Dd<DdType::CUDD> const& getCube() const;
+            
+            // The name of the meta variable.
+            std::string name;
+            
+            // The type of the variable.
+            MetaVariableType type;
+            
+            // The lowest value of the range of the variable.
+            int_fast64_t low;
+            
+            // The highest value of the range of the variable.
+            int_fast64_t high;
+            
+            // The vector of variables that are used to encode the meta variable.
+            std::vector<Dd<DdType::CUDD>> ddVariables;
+            
+            // The cube consisting of all variables that encode the meta variable.
+            Dd<DdType::CUDD> cube;
+            
+            // A pointer to the manager responsible for this meta variable.
+            std::shared_ptr<DdManager<DdType::CUDD>> manager;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_DDMETAVARIABLE_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp
deleted file mode 100644
index 453b83cc8..000000000
--- a/src/storage/dd/DdMetaVariable.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "src/storage/dd/DdMetaVariable.h"
-#include "src/storage/dd/CuddDdManager.h"
-
-namespace storm {
-    namespace dd {
-        template<DdType Type>
-        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), type(MetaVariableType::Int), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
-            // Create the cube of all variables of this meta variable.
-            for (auto const& ddVariable : this->ddVariables) {
-                this->cube *= ddVariable;
-            }
-        }
-        
-        template<DdType Type>
-        DdMetaVariable<Type>::DdMetaVariable(std::string const& name, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager) : name(name), type(MetaVariableType::Bool), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
-            // Create the cube of all variables of this meta variable.
-            for (auto const& ddVariable : this->ddVariables) {
-                this->cube *= ddVariable;
-            }
-        }
-        
-        template<DdType Type>
-        std::string const& DdMetaVariable<Type>::getName() const {
-            return this->name;
-        }
-        
-        template<DdType Type>
-        typename DdMetaVariable<Type>::MetaVariableType DdMetaVariable<Type>::getType() const {
-            return this->type;
-        }
-        
-        template<DdType Type>
-        int_fast64_t DdMetaVariable<Type>::getLow() const {
-            return this->low;
-        }
-
-        template<DdType Type>
-        int_fast64_t DdMetaVariable<Type>::getHigh() const {
-            return this->high;
-        }
-        
-        template<DdType Type>
-        std::size_t DdMetaVariable<Type>::getNumberOfDdVariables() const {
-            return this->ddVariables.size();
-        }
-        
-        template<DdType Type>
-        std::shared_ptr<DdManager<Type>> DdMetaVariable<Type>::getDdManager() const {
-            return this->manager;
-        }
-
-        template<DdType Type>
-        std::vector<Dd<Type>> const& DdMetaVariable<Type>::getDdVariables() const {
-            return this->ddVariables;
-        }
-        
-        template<DdType Type>
-        Dd<Type> const& DdMetaVariable<Type>::getCube() const {
-            return this->cube;
-        }
-        
-        // Explicitly instantiate DdMetaVariable.
-        template class DdMetaVariable<DdType::CUDD>;
-    }
-}
\ No newline at end of file
diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h
index 47936d805..b85b23c1c 100644
--- a/src/storage/dd/DdMetaVariable.h
+++ b/src/storage/dd/DdMetaVariable.h
@@ -1,137 +1,13 @@
-#ifndef STORM_STORAGE_DD_DDMETAVARIABLE_H_
-#define STORM_STORAGE_DD_DDMETAVARIABLE_H_
+#ifndef STORM_STORAGE_DD_DDMETAVARIBLE_H_
+#define STORM_STORAGE_DD_DDMETAVARIBLE_H_
 
-#include <memory>
-#include <vector>
-#include <cstdint>
-#include <string>
-
-#include "utility/OsDetection.h"
-#include "src/storage/dd/CuddDd.h"
-#include "src/storage/expressions/Expression.h"
+#include "src/storage/dd/DdType.h"
 
 namespace storm {
     namespace dd {
-        // Forward-declare the DdManager class.
-        template<DdType Type> class DdManager;
-        
-        template <DdType Type>
-        class DdMetaVariable {
-        public:
-            // Declare the DdManager class as friend so it can access the internals of a meta variable.
-            friend class DdManager<Type>;
-            friend class Dd<Type>;
-            friend class DdForwardIterator<Type>;
-            
-            // An enumeration for all legal types of meta variables.
-            enum class MetaVariableType { Bool, Int };
-            
-            /*!
-             * Creates an integer meta variable with the given name and range bounds.
-             *
-             * @param name The name of the meta variable.
-             * @param low The lowest value of the range of the variable.
-             * @param high The highest value of the range of the variable.
-             * @param ddVariables The vector of variables used to encode this variable.
-             * @param manager A pointer to the manager that is responsible for this meta variable.
-             */
-            DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
-            
-            /*!
-             * Creates a boolean meta variable with the given name.
-             * @param name The name of the meta variable.
-             * @param ddVariables The vector of variables used to encode this variable.
-             * @param manager A pointer to the manager that is responsible for this meta variable.
-             */
-            DdMetaVariable(std::string const& name, std::vector<Dd<Type>> const& ddVariables, std::shared_ptr<DdManager<Type>> manager);
-            
-            // Explictly generate all default versions of copy/move constructors/assignments.
-            DdMetaVariable(DdMetaVariable const& other) = default;
-			DdMetaVariable& operator=(DdMetaVariable const& other) = default;
-#ifndef WINDOWS
-            DdMetaVariable(DdMetaVariable&& other) = default;
-            DdMetaVariable& operator=(DdMetaVariable&& other) = default;
-#endif
-            
-            /*!
-             * Retrieves the name of the meta variable.
-             *
-             * @return The name of the variable.
-             */
-            std::string const& getName() const;
-            
-            /*!
-             * Retrieves the type of the meta variable.
-             *
-             * @return The type of the meta variable.
-             */
-            MetaVariableType getType() const;
-            
-            /*!
-             * Retrieves the lowest value of the range of the variable.
-             *
-             * @return The lowest value of the range of the variable.
-             */
-            int_fast64_t getLow() const;
-            
-            /*!
-             * Retrieves the highest value of the range of the variable.
-             *
-             * @return The highest value of the range of the variable.
-             */
-            int_fast64_t getHigh() const;
-            
-            /*!
-             * Retrieves the manager that is responsible for this meta variable.
-             *
-             * A pointer to the manager that is responsible for this meta variable.
-             */
-            std::shared_ptr<DdManager<Type>> getDdManager() const;
-            
-            /*!
-             * Retrieves the number of DD variables for this meta variable.
-             *
-             * @return The number of DD variables for this meta variable.
-             */
-            std::size_t getNumberOfDdVariables() const;
-            
-        private:
-            /*!
-             * Retrieves the variables used to encode the meta variable.
-             *
-             * @return A vector of variables used to encode the meta variable.
-             */
-            std::vector<Dd<Type>> const& getDdVariables() const;
-            
-            /*!
-             * Retrieves the cube of all variables that encode this meta variable.
-             *
-             * @return The cube of all variables that encode this meta variable.
-             */
-            Dd<Type> const& getCube() const;
-            
-            // The name of the meta variable.
-            std::string name;
-            
-            // The type of the variable.
-            MetaVariableType type;
-            
-            // The lowest value of the range of the variable.
-            int_fast64_t low;
-            
-            // The highest value of the range of the variable.
-            int_fast64_t high;
-            
-            // The vector of variables that are used to encode the meta variable.
-            std::vector<Dd<Type>> ddVariables;
-            
-            // The cube consisting of all variables that encode the meta variable.
-            Dd<Type> cube;
-            
-            // A pointer to the manager responsible for this meta variable.
-            std::shared_ptr<DdManager<Type>> manager;
-        };
+        // Declare DdMetaVariable class so we can then specialize it for the different DD types.
+        template<DdType Type> class DdMetaVariable;
     }
 }
 
-#endif /* STORM_STORAGE_DD_DDMETAVARIABLE_H_ */
\ No newline at end of file
+#endif /* STORM_STORAGE_DD_DDMETAVARIBLE_H_ */
\ No newline at end of file

From 9e506f40bc7a848d3f78e5a45055722c4b76b3d4 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 26 May 2014 13:29:40 +0200
Subject: [PATCH 125/147] Some fixes for MSVC. :P

Former-commit-id: 1429e54f73dea59096796d35d511a48310759987
---
 src/storage/dd/CuddDd.cpp                | 2 +-
 src/storage/dd/CuddDdForwardIterator.cpp | 2 +-
 src/storage/dd/CuddDdMetaVariable.cpp    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index cdff92894..96bdc9e77 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -477,7 +477,7 @@ namespace storm {
             int* cube;
             double value;
             DdGen* generator = this->getCuddAdd().FirstCube(&cube, &value);
-            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, Cudd_IsGenEmpty(generator), &this->getContainedMetaVariableNames(), enumerateDontCareMetaVariables);
+            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, static_cast<bool>(Cudd_IsGenEmpty(generator)), &this->getContainedMetaVariableNames(), enumerateDontCareMetaVariables);
         }
         
         DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::end(bool enumerateDontCareMetaVariables) const {
diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp
index cce5c112c..4eda09907 100644
--- a/src/storage/dd/CuddDdForwardIterator.cpp
+++ b/src/storage/dd/CuddDdForwardIterator.cpp
@@ -70,7 +70,7 @@ namespace storm {
             if (this->relevantDontCareDdVariables.empty() || this->cubeCounter >= std::pow(2, this->relevantDontCareDdVariables.size()) - 1) {
                 // Get the next cube and check for emptiness.
                 ABDD::NextCube(generator, &cube, &value);
-                this->isAtEnd = Cudd_IsGenEmpty(generator);
+                this->isAtEnd = static_cast<bool>(Cudd_IsGenEmpty(generator));
 
                 // In case we are not done yet, we get ready to treat the next cube.
                 if (!this->isAtEnd) {
diff --git a/src/storage/dd/CuddDdMetaVariable.cpp b/src/storage/dd/CuddDdMetaVariable.cpp
index b7f45dbe3..303cb192c 100644
--- a/src/storage/dd/CuddDdMetaVariable.cpp
+++ b/src/storage/dd/CuddDdMetaVariable.cpp
@@ -21,7 +21,7 @@ namespace storm {
             return this->name;
         }
         
-        typename DdMetaVariable<DdType::CUDD>::MetaVariableType DdMetaVariable<DdType::CUDD>::getType() const {
+        DdMetaVariable<DdType::CUDD>::MetaVariableType DdMetaVariable<DdType::CUDD>::getType() const {
             return this->type;
         }
         

From b1f22c17478905e5305c416ef1e11ee65e2d664e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 30 May 2014 17:34:09 +0200
Subject: [PATCH 126/147] Added shortcut DD interface to compute
 \'greaterZero\' on a DD.

Former-commit-id: 65585533fd8c50fabe9870e248b35361a6365e36
---
 src/storage/dd/CuddDd.cpp | 4 ++++
 src/storage/dd/CuddDd.h   | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 96bdc9e77..d3789d073 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -314,6 +314,10 @@ namespace storm {
             return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
         }
         
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::greaterZero() const {
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().BddStrictThreshold(0).Add(), this->getContainedMetaVariableNames());
+        }
+        
         uint_fast64_t Dd<DdType::CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
             for (auto const& metaVariableName : this->containedMetaVariableNames) {
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 9f638d329..4de29e513 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -291,6 +291,14 @@ namespace storm {
              */
             Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) const;
             
+            /*!
+             * Computes a DD that represents the function in which all assignments with a function value strictly larger
+             * than zero are mapped to one and all others to zero.
+             *
+             * @return The resulting DD.
+             */
+            Dd<DdType::CUDD> greaterZero() const;
+            
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.
              *

From 151324198508f619446cf56b1af0c3d3748efc67 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 30 May 2014 19:53:35 +0200
Subject: [PATCH 127/147] Added functions for more efficiently retrieving the
 DD for 'greater than constant', 'greater or equal than constant' and
 'notZero'.

Former-commit-id: 9d80c29f271a83bc492027443a8d2e430f97f47c
---
 src/storage/dd/CuddDd.cpp | 12 ++++++++++--
 src/storage/dd/CuddDd.h   | 22 ++++++++++++++++++++--
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index d3789d073..fde9d008a 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -314,10 +314,18 @@ namespace storm {
             return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
         }
         
-        Dd<DdType::CUDD> Dd<DdType::CUDD>::greaterZero() const {
-            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().BddStrictThreshold(0).Add(), this->getContainedMetaVariableNames());
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::greater(double value) const {
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().BddStrictThreshold(value).Add(), this->getContainedMetaVariableNames());
         }
         
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::greaterOrEqual(double value) const {
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().BddThreshold(value).Add(), this->getContainedMetaVariableNames());
+        }
+
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::notZero() const {
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().BddPattern().Add(), this->getContainedMetaVariableNames());
+        }
+
         uint_fast64_t Dd<DdType::CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
             for (auto const& metaVariableName : this->containedMetaVariableNames) {
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 4de29e513..6d91960ba 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -293,11 +293,29 @@ namespace storm {
             
             /*!
              * Computes a DD that represents the function in which all assignments with a function value strictly larger
-             * than zero are mapped to one and all others to zero.
+             * than the given value are mapped to one and all others to zero.
              *
+             * @param value The value used for the comparison.
              * @return The resulting DD.
              */
-            Dd<DdType::CUDD> greaterZero() const;
+            Dd<DdType::CUDD> greater(double value) const;
+
+            /*!
+             * Computes a DD that represents the function in which all assignments with a function value larger or equal
+             * to the given value are mapped to one and all others to zero.
+             *
+             * @param value The value used for the comparison.
+             * @return The resulting DD.
+             */
+            Dd<DdType::CUDD> greaterOrEqual(double value) const;
+            
+            /*!
+             * Computes a DD that represents the function in which all assignments with a function value unequal to zero
+             * are mapped to one and all others to zero.
+             *
+             * @return The resulting DD.
+             */
+            Dd<DdType::CUDD> notZero() const;
             
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.

From 60b2145461be301510ae96d9da7adff42c00a1eb Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 31 May 2014 21:20:56 +0200
Subject: [PATCH 128/147] Added function to DD interface that creates a nested
 if-then-else expression that represents the very same function as the DD.
 Added a test for this functionality. Added some methods offereded by Cudd to
 simplify DDs.

Former-commit-id: 4fc816f64b4e68cfea8bd59d48fa8663458990a3
---
 src/storage/dd/CuddDd.cpp              | 31 +++++++++++++++++
 src/storage/dd/CuddDd.h                | 46 ++++++++++++++++++++++++++
 src/storage/dd/CuddDdManager.h         |  1 -
 test/functional/storage/CuddDdTest.cpp | 33 ++++++++++++++++++
 4 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index fde9d008a..f12c4bfa8 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -325,6 +325,24 @@ namespace storm {
         Dd<DdType::CUDD> Dd<DdType::CUDD>::notZero() const {
             return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().BddPattern().Add(), this->getContainedMetaVariableNames());
         }
+        
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::constrain(Dd<DdType::CUDD> const& constraint) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(constraint.getContainedMetaVariableNames().begin(), constraint.getContainedMetaVariableNames().end());
+            
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Constrain(constraint.getCuddAdd()), metaVariableNames);
+        }
+        
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::restrict(Dd<DdType::CUDD> const& constraint) const {
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(constraint.getContainedMetaVariableNames().begin(), constraint.getContainedMetaVariableNames().end());
+            
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Restrict(constraint.getCuddAdd()), metaVariableNames);
+        }
+        
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::getSupport() const {
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Support().Add(), this->getContainedMetaVariableNames());
+        }
 
         uint_fast64_t Dd<DdType::CUDD>::getNonZeroCount() const {
             std::size_t numberOfDdVariables = 0;
@@ -496,6 +514,19 @@ namespace storm {
             return DdForwardIterator<DdType::CUDD>(this->getDdManager(), nullptr, nullptr, 0, true, nullptr, enumerateDontCareMetaVariables);
         }
         
+        storm::expressions::Expression Dd<DdType::CUDD>::toExpression() const {
+            return toExpressionRecur(this->getCuddAdd().getNode(), this->getDdManager()->getDdVariableNames());
+        }
+        
+        storm::expressions::Expression Dd<DdType::CUDD>::toExpressionRecur(DdNode const* dd, std::vector<std::string> const& variableNames) {
+            // If the DD is a terminal node, we can simply return a constant expression.
+            if (Cudd_IsConstant(dd)) {
+                return storm::expressions::Expression::createDoubleLiteral(static_cast<double>(Cudd_V(dd)));
+            } else {
+                return storm::expressions::Expression::createBooleanVariable(variableNames[dd->index]).ite(toExpressionRecur(Cudd_T(dd), variableNames), toExpressionRecur(Cudd_E(dd), variableNames));
+            }
+        }
+        
         std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
             dd.exportToDot();
             return out;
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 6d91960ba..bf879fa34 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -8,6 +8,7 @@
 
 #include "src/storage/dd/Dd.h"
 #include "src/storage/dd/CuddDdForwardIterator.h"
+#include "src/storage/expressions/Expression.h"
 #include "src/utility/OsDetection.h"
 
 // Include the C++-interface of CUDD.
@@ -317,6 +318,33 @@ namespace storm {
              */
             Dd<DdType::CUDD> notZero() const;
             
+            /*!
+             * Computes the constraint of the current DD with the given constraint. That is, the function value of the
+             * resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
+             * and may be different otherwise.
+             *
+             * @param constraint The constraint to use for the operation.
+             * @return The resulting DD.
+             */
+            Dd<DdType::CUDD> constrain(Dd<DdType::CUDD> const& constraint) const;
+            
+            /*!
+             * Computes the restriction of the current DD with the given constraint. That is, the function value of the
+             * resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
+             * and may be different otherwise.
+             *
+             * @param constraint The constraint to use for the operation.
+             * @return The resulting DD.
+             */
+            Dd<DdType::CUDD> restrict(Dd<DdType::CUDD> const& constraint) const;
+            
+            /*!
+             * Retrieves the support of the current DD.
+             *
+             * @return The support represented as a DD.
+             */
+            Dd<DdType::CUDD> getSupport() const;
+            
             /*!
              * Retrieves the number of encodings that are mapped to a non-zero value.
              *
@@ -481,6 +509,15 @@ namespace storm {
              */
             DdForwardIterator<DdType::CUDD> end(bool enumerateDontCareMetaVariables = true) const;
             
+            /*!
+             * Converts the DD into a (heavily nested) if-then-else expression that represents the very same function.
+             * The variable names used in the expression are derived from the meta variable name with a suffix ".i"
+             * expressing that the variable is the i-th bit of the meta variable. 
+             *
+             * @return The resulting expression.
+             */
+            storm::expressions::Expression toExpression() const;
+            
             friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
         private:
             /*!
@@ -511,6 +548,15 @@ namespace storm {
              */
             void removeContainedMetaVariable(std::string const& metaVariableName);
             
+            /*!
+             * Performs the recursive step of toExpression on the given DD.
+             *
+             * @param dd The dd to translate into an expression.
+             * @param variableNames The names of the variables to use in the expression.
+             * @return The resulting expression.
+             */
+            static storm::expressions::Expression toExpressionRecur(DdNode const* dd, std::vector<std::string> const& variableNames);
+            
             /*!
              * Creates a DD that encapsulates the given CUDD ADD.
              *
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 14ea4d8a3..a570224c3 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -138,7 +138,6 @@ namespace storm {
              */
             void triggerReordering();
             
-        protected:
             /*!
              * Retrieves the meta variable with the given name if it exists.
              *
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index f39e4ad48..c84def017 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -308,3 +308,36 @@ TEST(CuddDd, ForwardIteratorTest) {
     }
     EXPECT_EQ(1, numberOfValuations);
 }
+
+TEST(CuddDd, ToExpressionTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
+    manager->addMetaVariable("x", 1, 9);
+
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd;
+    ASSERT_NO_THROW(dd = manager->getIdentity("x"));
+    
+    storm::expressions::Expression ddAsExpression;
+    ASSERT_NO_THROW(ddAsExpression = dd.toExpression());
+
+    storm::expressions::SimpleValuation valuation;
+    for (std::size_t bit = 0; bit < manager->getMetaVariable("x").getNumberOfDdVariables(); ++bit) {
+        valuation.addBooleanIdentifier("x." + std::to_string(bit));
+    }
+    
+    storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariable = manager->getMetaVariable("x");
+
+    for (auto valuationValuePair : dd) {
+        for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
+            // Check if the i-th bit is set or not and modify the valuation accordingly.
+            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1 << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
+                valuation.setBooleanValue("x." + std::to_string(i), true);
+            } else {
+                valuation.setBooleanValue("x." + std::to_string(i), false);
+            }
+        }
+        
+        // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
+        // same value as the current value obtained from the DD.
+        EXPECT_EQ(valuationValuePair.second, ddAsExpression.evaluateAsDouble(&valuation));
+    }
+}
\ No newline at end of file

From e79fa509998e29e3905c4cbf947af504d21e69bf Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 31 May 2014 21:29:18 +0200
Subject: [PATCH 129/147] Changed naming of DD variables belonging to one meta
 variable slightly: only integer-valued meta variables now get a '.i' suffix
 to denote their i-th bit.

Former-commit-id: 771312ac31357dae28db63a98ad55dcd86ad1b18
---
 src/storage/dd/CuddDd.h          |  7 ++++---
 src/storage/dd/CuddDdManager.cpp | 10 ++++++++--
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index bf879fa34..279b2c2fa 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -511,8 +511,9 @@ namespace storm {
             
             /*!
              * Converts the DD into a (heavily nested) if-then-else expression that represents the very same function.
-             * The variable names used in the expression are derived from the meta variable name with a suffix ".i"
-             * expressing that the variable is the i-th bit of the meta variable. 
+             * The variable names used in the expression are derived from the meta variable name and are extended with a
+             * suffix ".i" if the meta variable is integer-valued, expressing that the variable is the i-th bit of the
+             * meta variable.
              *
              * @return The resulting expression.
              */
@@ -562,7 +563,7 @@ namespace storm {
              *
              * @param ddManager The manager responsible for this DD.
              * @param cuddAdd The CUDD ADD to store.
-             * @param
+             * @param containedMetaVariableNames The names of the meta variables that appear in the DD.
              */
             Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
             
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index fd26a782c..f23734ad2 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -183,8 +183,14 @@ namespace storm {
             std::vector<std::pair<ADD, std::string>> variableNamePairs;
             for (auto const& nameMetaVariablePair : this->metaVariableMap) {
                 DdMetaVariable<DdType::CUDD> const& metaVariable = nameMetaVariablePair.second;
-                for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
-                    variableNamePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getCuddAdd(), metaVariable.getName() + "." + std::to_string(variableIndex));
+                // If the meta variable is of type bool, we don't need to suffix it with the bit number.
+                if (metaVariable.getType() == DdMetaVariable<storm::dd::DdType::CUDD>::MetaVariableType::Bool) {
+                    variableNamePairs.emplace_back(metaVariable.getDdVariables().front().getCuddAdd(), metaVariable.getName());
+                } else {
+                    // For integer-valued meta variables, we, however, have to add the suffix.
+                    for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
+                        variableNamePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getCuddAdd(), metaVariable.getName() + "." + std::to_string(variableIndex));
+                    }
                 }
             }
             

From 7b2def2b11e666de28e2ad2e32471859c7eff476 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 1 Jun 2014 11:22:55 +0200
Subject: [PATCH 130/147] Added function to retrieve the minterms of a DD as an
 expression and added corresponding test.

Former-commit-id: afaf1f02a3928d294fba3e5e64fc51e01ea4b31f
---
 src/storage/dd/CuddDd.cpp              | 34 +++++++++++++++++++++++++
 src/storage/dd/CuddDd.h                | 20 +++++++++++++++
 test/functional/storage/CuddDdTest.cpp | 35 ++++++++++++++++++++++++++
 3 files changed, 89 insertions(+)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index f12c4bfa8..e5f62f80d 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -518,6 +518,16 @@ namespace storm {
             return toExpressionRecur(this->getCuddAdd().getNode(), this->getDdManager()->getDdVariableNames());
         }
         
+        storm::expressions::Expression Dd<DdType::CUDD>::getMintermExpression() const {
+            // Note that we first transform the ADD into a BDD to convert all non-zero terminals to ones and therefore
+            // make the DD more compact.
+            Dd<DdType::CUDD> tmp(this->getDdManager(), this->getCuddAdd().BddPattern().Add(), this->getContainedMetaVariableNames());
+            tmp.exportToDot("tmp.dot");
+            
+            
+            return getMintermExpressionRecur(this->getDdManager()->getCuddManager().getManager(), this->getCuddAdd().BddPattern().getNode(), this->getDdManager()->getDdVariableNames());
+        }
+        
         storm::expressions::Expression Dd<DdType::CUDD>::toExpressionRecur(DdNode const* dd, std::vector<std::string> const& variableNames) {
             // If the DD is a terminal node, we can simply return a constant expression.
             if (Cudd_IsConstant(dd)) {
@@ -527,6 +537,30 @@ namespace storm {
             }
         }
         
+        storm::expressions::Expression Dd<DdType::CUDD>::getMintermExpressionRecur(::DdManager* manager, DdNode const* dd, std::vector<std::string> const& variableNames) {
+            // If the DD is a terminal node, we can simply return a constant expression.
+            if (Cudd_IsConstant(dd)) {
+                if (Cudd_IsComplement(dd)) {
+                    return storm::expressions::Expression::createBooleanLiteral(false);
+                } else {
+                    return storm::expressions::Expression::createBooleanLiteral((dd == Cudd_ReadOne(manager)) ? true : false);
+                }
+            } else {
+                // Get regular versions of the pointers.
+                DdNode* regularDd = Cudd_Regular(dd);
+                DdNode* thenDd = Cudd_T(regularDd);
+                DdNode* elseDd = Cudd_E(regularDd);
+                
+                // Compute expression recursively.
+                storm::expressions::Expression result = storm::expressions::Expression::createBooleanVariable(variableNames[dd->index]).ite(getMintermExpressionRecur(manager, thenDd, variableNames), getMintermExpressionRecur(manager, elseDd, variableNames));
+                if (Cudd_IsComplement(dd)) {
+                    result = !result;
+                }
+                
+                return result;
+            }
+        }
+        
         std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
             dd.exportToDot();
             return out;
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 279b2c2fa..b269c4dfd 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -518,6 +518,16 @@ namespace storm {
              * @return The resulting expression.
              */
             storm::expressions::Expression toExpression() const;
+
+            /*!
+             * Converts the DD into a (heavily nested) if-then-else (with negations) expression that evaluates to true
+             * if and only if the assignment is minterm of the DD. The variable names used in the expression are derived
+             * from the meta variable name and are extended with a suffix ".i" if the meta variable is integer-valued,
+             * expressing that the variable is the i-th bit of the meta variable.
+             *
+             * @return The resulting expression.
+             */
+            storm::expressions::Expression getMintermExpression() const;
             
             friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
         private:
@@ -558,6 +568,16 @@ namespace storm {
              */
             static storm::expressions::Expression toExpressionRecur(DdNode const* dd, std::vector<std::string> const& variableNames);
             
+            /*!
+             * Performs the recursive step of getMintermExpression on the given DD.
+             *
+             * @param manager The manager of the DD.
+             * @param dd The dd whose minterms to translate into an expression.
+             * @param variableNames The names of the variables to use in the expression.
+             * @return The resulting expression.
+             */
+            static storm::expressions::Expression getMintermExpressionRecur(::DdManager* manager, DdNode const* dd, std::vector<std::string> const& variableNames);
+            
             /*!
              * Creates a DD that encapsulates the given CUDD ADD.
              *
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index c84def017..e425bca51 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -340,4 +340,39 @@ TEST(CuddDd, ToExpressionTest) {
         // same value as the current value obtained from the DD.
         EXPECT_EQ(valuationValuePair.second, ddAsExpression.evaluateAsDouble(&valuation));
     }
+    
+    storm::expressions::Expression mintermExpression = dd.getMintermExpression();
+    
+    // Check whether all minterms are covered.
+    for (auto valuationValuePair : dd) {
+        for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
+            // Check if the i-th bit is set or not and modify the valuation accordingly.
+            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1 << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
+                valuation.setBooleanValue("x." + std::to_string(i), true);
+            } else {
+                valuation.setBooleanValue("x." + std::to_string(i), false);
+            }
+        }
+        
+        // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
+        // same value as the current value obtained from the DD.
+        EXPECT_TRUE(mintermExpression.evaluateAsBool(&valuation));
+    }
+    
+    // Now check no additional minterms are covered.
+    dd = !dd;
+    for (auto valuationValuePair : dd) {
+        for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
+            // Check if the i-th bit is set or not and modify the valuation accordingly.
+            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1 << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
+                valuation.setBooleanValue("x." + std::to_string(i), true);
+            } else {
+                valuation.setBooleanValue("x." + std::to_string(i), false);
+            }
+        }
+        
+        // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
+        // same value as the current value obtained from the DD.
+        EXPECT_FALSE(mintermExpression.evaluateAsBool(&valuation));
+    }
 }
\ No newline at end of file

From 63f55b38f0af79f797fd800a9473fc72f6373eb5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 1 Jun 2014 14:14:25 +0200
Subject: [PATCH 131/147] Removed debug output that was - of course - never
 there. (You saw nothing!)

Former-commit-id: 9249928f54197fc63273b5b004f83f0f11fa11d4
---
 src/storage/dd/CuddDd.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index e5f62f80d..6c9077184 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -522,9 +522,6 @@ namespace storm {
             // Note that we first transform the ADD into a BDD to convert all non-zero terminals to ones and therefore
             // make the DD more compact.
             Dd<DdType::CUDD> tmp(this->getDdManager(), this->getCuddAdd().BddPattern().Add(), this->getContainedMetaVariableNames());
-            tmp.exportToDot("tmp.dot");
-            
-            
             return getMintermExpressionRecur(this->getDdManager()->getCuddManager().getManager(), this->getCuddAdd().BddPattern().getNode(), this->getDdManager()->getDdVariableNames());
         }
         

From b7ad4398e2e5762a48baf67b1856171eb85c41f9 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Thu, 5 Jun 2014 00:28:05 +0200
Subject: [PATCH 132/147] Fixed an error in the interface of the LpSolvers.

Former-commit-id: 65e415efb29a70f61b90ba9887b7f49636592b6d
---
 src/solver/GurobiLpSolver.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/solver/GurobiLpSolver.h b/src/solver/GurobiLpSolver.h
index 90bef47eb..f078ef6dd 100644
--- a/src/solver/GurobiLpSolver.h
+++ b/src/solver/GurobiLpSolver.h
@@ -176,7 +176,7 @@ namespace storm {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             
-            virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
+            virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override {
                 throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support.";
             }
             

From b5cb0cde1d814b441a51d25f6722c61c91153393 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Thu, 5 Jun 2014 00:28:28 +0200
Subject: [PATCH 133/147] Fixed a typo in the StormOptions.cpp

Former-commit-id: a23d47d1129ee24e6656a5d79fd614c19f4be362
---
 src/utility/StormOptions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/utility/StormOptions.cpp b/src/utility/StormOptions.cpp
index 29f6dccfd..48b7aa3e0 100644
--- a/src/utility/StormOptions.cpp
+++ b/src/utility/StormOptions.cpp
@@ -28,7 +28,7 @@ bool storm::utility::StormOptions::optionsRegistered = storm::settings::Settings
     
 	settings->addOption(storm::settings::OptionBuilder("StoRM Main", "counterExample", "", "Generates a counterexample for the given PRCTL formulas if not satisfied by the model").addArgument(storm::settings::ArgumentBuilder::createStringArgument("outputPath", "The path to the directory to write the generated counterexample files to.").build()).build());
 
-	settings->addOption(storm::settings::OptionBuilder("StoRM Main", "transitionRewards", "", "If specified, the transition rewards are read from this file and added to the explicit model. Note that this requires an explicit model.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("transitionRewardsFileName", "The file from which to read the rransition rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build());
+	settings->addOption(storm::settings::OptionBuilder("StoRM Main", "transitionRewards", "", "If specified, the transition rewards are read from this file and added to the explicit model. Note that this requires an explicit model.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("transitionRewardsFileName", "The file from which to read the transition rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build());
     
 	settings->addOption(storm::settings::OptionBuilder("StoRM Main", "stateRewards", "", "If specified, the state rewards are read from this file and added to the explicit model. Note that this requires an explicit model.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("stateRewardsFileName", "The file from which to read the state rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build());
     

From 03399375f8aaa7dfa51d2a01287dd11fb26fda17 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Thu, 5 Jun 2014 00:29:36 +0200
Subject: [PATCH 134/147] Fixed an unintended 32bit shift being expanded to 64
 bit

Former-commit-id: b2adc2a5baaa730aefd11a7a80ad93305a769f69
---
 test/functional/storage/CuddDdTest.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index e425bca51..391f8c96d 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -329,7 +329,7 @@ TEST(CuddDd, ToExpressionTest) {
     for (auto valuationValuePair : dd) {
         for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
             // Check if the i-th bit is set or not and modify the valuation accordingly.
-            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1 << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
+            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
                 valuation.setBooleanValue("x." + std::to_string(i), true);
             } else {
                 valuation.setBooleanValue("x." + std::to_string(i), false);
@@ -347,7 +347,7 @@ TEST(CuddDd, ToExpressionTest) {
     for (auto valuationValuePair : dd) {
         for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
             // Check if the i-th bit is set or not and modify the valuation accordingly.
-            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1 << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
+            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
                 valuation.setBooleanValue("x." + std::to_string(i), true);
             } else {
                 valuation.setBooleanValue("x." + std::to_string(i), false);
@@ -364,7 +364,7 @@ TEST(CuddDd, ToExpressionTest) {
     for (auto valuationValuePair : dd) {
         for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
             // Check if the i-th bit is set or not and modify the valuation accordingly.
-            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1 << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
+            if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
                 valuation.setBooleanValue("x." + std::to_string(i), true);
             } else {
                 valuation.setBooleanValue("x." + std::to_string(i), false);

From 7ab2a84c0f68dbd22dced0ac0275c0cda86c3649 Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Thu, 5 Jun 2014 00:30:28 +0200
Subject: [PATCH 135/147] Small beauty fixes to the Cudd Interface

Former-commit-id: 631d5a20bdc0d7dc0c45f9f2952e61353e1fde7d
---
 src/storage/dd/CuddDd.cpp                | 2 +-
 src/storage/dd/CuddDdForwardIterator.cpp | 2 +-
 src/storage/dd/CuddDdManager.cpp         | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 6c9077184..f02e0d7a1 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -507,7 +507,7 @@ namespace storm {
             int* cube;
             double value;
             DdGen* generator = this->getCuddAdd().FirstCube(&cube, &value);
-            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, static_cast<bool>(Cudd_IsGenEmpty(generator)), &this->getContainedMetaVariableNames(), enumerateDontCareMetaVariables);
+            return DdForwardIterator<DdType::CUDD>(this->getDdManager(), generator, cube, value, (Cudd_IsGenEmpty(generator) != 0), &this->getContainedMetaVariableNames(), enumerateDontCareMetaVariables);
         }
         
         DdForwardIterator<DdType::CUDD> Dd<DdType::CUDD>::end(bool enumerateDontCareMetaVariables) const {
diff --git a/src/storage/dd/CuddDdForwardIterator.cpp b/src/storage/dd/CuddDdForwardIterator.cpp
index 4eda09907..4a990746e 100644
--- a/src/storage/dd/CuddDdForwardIterator.cpp
+++ b/src/storage/dd/CuddDdForwardIterator.cpp
@@ -70,7 +70,7 @@ namespace storm {
             if (this->relevantDontCareDdVariables.empty() || this->cubeCounter >= std::pow(2, this->relevantDontCareDdVariables.size()) - 1) {
                 // Get the next cube and check for emptiness.
                 ABDD::NextCube(generator, &cube, &value);
-                this->isAtEnd = static_cast<bool>(Cudd_IsGenEmpty(generator));
+                this->isAtEnd = (Cudd_IsGenEmpty(generator) != 0);
 
                 // In case we are not done yet, we get ready to treat the next cube.
                 if (!this->isAtEnd) {
diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index f23734ad2..3f0a2abed 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -33,7 +33,7 @@ bool CuddOptionsRegistered = storm::settings::Settings::registerNewModule([] (st
 namespace storm {
     namespace dd {
         DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
-            this->cuddManager.SetMaxMemory(storm::settings::Settings::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024 * 1024);
+            this->cuddManager.SetMaxMemory(static_cast<unsigned long>(storm::settings::Settings::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024ul * 1024ul));
             this->cuddManager.SetEpsilon(storm::settings::Settings::getInstance()->getOptionByLongName("cuddprec").getArgument(0).getValueAsDouble());
         }
         

From 5503e91bb36d2d7a781d8b349f35ab5d0716118a Mon Sep 17 00:00:00 2001
From: PBerger <philipp.berger@rwth-aachen.de>
Date: Thu, 5 Jun 2014 00:31:36 +0200
Subject: [PATCH 136/147] Added detailed time measurement using std::chrono,
 leading to more useful information for comparison against Prism, etc.

Former-commit-id: 98e3e8e0976c7dcf87d3df9ffda0044538268c28
---
 src/storm.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/storm.cpp b/src/storm.cpp
index c7b40247a..db3f233fb 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -117,8 +117,8 @@ void printUsage() {
 	double userTime = uLargeInteger.QuadPart / 10000.0;
 
 	std::cout << "CPU Time: " << std::endl;
-	std::cout << "\tKernel Time: " << std::setprecision(3) << kernelTime << std::endl;
-	std::cout << "\tUser Time: " << std::setprecision(3) << userTime << std::endl;
+	std::cout << "\tKernel Time: " << std::setprecision(5) << kernelTime << "ms" << std::endl;
+	std::cout << "\tUser Time: " << std::setprecision(5) << userTime << "ms" << std::endl;
 #endif
 }
 
@@ -451,6 +451,9 @@ int main(const int argc, const char* argv[]) {
 			stormSetAlarm(timeout);
         }
         
+		// Execution Time measurement, start
+		std::chrono::high_resolution_clock::time_point executionStart = std::chrono::high_resolution_clock::now();
+
 		// Now, the settings are received and the specified model is parsed. The actual actions taken depend on whether
         // the model was provided in explicit or symbolic format.
 		if (s->isSet("explicit")) {
@@ -468,6 +471,10 @@ int main(const int argc, const char* argv[]) {
 
 			std::shared_ptr<storm::models::AbstractModel<double>> model = storm::parser::AutoParser::parseModel(chosenTransitionSystemFile, chosenLabelingFile, chosenStateRewardsFile, chosenTransitionRewardsFile);
 
+			// Model Parsing Time Measurement, End
+			std::chrono::high_resolution_clock::time_point parsingEnd = std::chrono::high_resolution_clock::now();
+			std::cout << "Parsing the given model took " << std::chrono::duration_cast<std::chrono::milliseconds>(parsingEnd - executionStart).count() << " milliseconds." << std::endl;
+
             if (s->isSet("exportdot")) {
                 std::ofstream outputFileStream;
                 outputFileStream.open(s->getOptionByLongName("exportdot").getArgument(0).getValueAsString(), std::ofstream::out);
@@ -475,11 +482,16 @@ int main(const int argc, const char* argv[]) {
                 outputFileStream.close();
             }
             
-			//Should there be a counterexample generated in case the formula is not satisfied?
+			// Should there be a counterexample generated in case the formula is not satisfied?
 			if(s->isSet("counterexample")) {
+				// Counterexample Time Measurement, Start
+				std::chrono::high_resolution_clock::time_point counterexampleStart = std::chrono::high_resolution_clock::now();
 
 				generateCounterExample(model);
 			
+				// Counterexample Time Measurement, End
+				std::chrono::high_resolution_clock::time_point counterexampleEnd = std::chrono::high_resolution_clock::now();
+				std::cout << "Generating the counterexample took " << std::chrono::duration_cast<std::chrono::milliseconds>(counterexampleEnd - counterexampleStart).count() << " milliseconds." << std::endl;
 			} else {
 				// Determine which engine is to be used to choose the right model checker.
 				LOG4CPLUS_DEBUG(logger, s->getOptionByLongName("matrixLibrary").getArgument(0).getValueAsString());
@@ -488,6 +500,9 @@ int main(const int argc, const char* argv[]) {
 				storm::modelchecker::prctl::AbstractModelChecker<double>* modelchecker = nullptr;
 				model->printModelInformationToStream(std::cout);
                 
+				// Modelchecking Time Measurement, Start
+				std::chrono::high_resolution_clock::time_point modelcheckingStart = std::chrono::high_resolution_clock::now();
+
 				switch (model->getType()) {
 				case storm::models::DTMC:
 					LOG4CPLUS_INFO(logger, "Model is a DTMC.");
@@ -529,8 +544,15 @@ int main(const int argc, const char* argv[]) {
 				if (modelchecker != nullptr) {
 					delete modelchecker;
 				}
+
+				// Modelchecking Time Measurement, End
+				std::chrono::high_resolution_clock::time_point modelcheckingEnd = std::chrono::high_resolution_clock::now();
+				std::cout << "Running the ModelChecker took " << std::chrono::duration_cast<std::chrono::milliseconds>(modelcheckingEnd - modelcheckingStart).count() << " milliseconds." << std::endl;
 			}
 		} else if (s->isSet("symbolic")) {
+			// Program Translation Time Measurement, Start
+			std::chrono::high_resolution_clock::time_point programTranslationStart = std::chrono::high_resolution_clock::now();
+
             // First, we build the model using the given symbolic model description and constant definitions.
             std::string const& programFile = s->getOptionByLongName("symbolic").getArgument(0).getValueAsString();
             std::string const& constants = s->getOptionByLongName("constants").getArgument(0).getValueAsString();
@@ -538,6 +560,10 @@ int main(const int argc, const char* argv[]) {
             std::shared_ptr<storm::models::AbstractModel<double>> model = storm::adapters::ExplicitModelAdapter<double>::translateProgram(program, constants);
             model->printModelInformationToStream(std::cout);
             
+			// Program Translation Time Measurement, End
+			std::chrono::high_resolution_clock::time_point programTranslationEnd = std::chrono::high_resolution_clock::now();
+			std::cout << "Parsing and translating the Symbolic Input took " << std::chrono::duration_cast<std::chrono::milliseconds>(programTranslationEnd - programTranslationStart).count() << " milliseconds." << std::endl;
+
             if (s->isSet("mincmd")) {
                 if (model->getType() != storm::models::MDP) {
                     LOG4CPLUS_ERROR(logger, "Minimal command counterexample generation is only supported for models of type MDP.");
@@ -549,6 +575,9 @@ int main(const int argc, const char* argv[]) {
                 // Determine whether we are required to use the MILP-version or the SAT-version.
                 bool useMILP = s->getOptionByLongName("mincmd").getArgumentByName("method").getValueAsString() == "milp";
                 
+				// MinCMD Time Measurement, Start
+				std::chrono::high_resolution_clock::time_point minCmdStart = std::chrono::high_resolution_clock::now();
+
                 // Now parse the property file and receive the list of parsed formulas.
                 std::string const& propertyFile = s->getOptionByLongName("mincmd").getArgumentByName("propertyFile").getValueAsString();
                 std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(propertyFile);
@@ -564,6 +593,10 @@ int main(const int argc, const char* argv[]) {
                     // Once we are done with the formula, delete it.
                     delete formulaPtr;
                 }
+
+				// MinCMD Time Measurement, End
+				std::chrono::high_resolution_clock::time_point minCmdEnd = std::chrono::high_resolution_clock::now();
+				std::cout << "Minimal command Counterexample generation took " << std::chrono::duration_cast<std::chrono::milliseconds>(minCmdStart - minCmdEnd).count() << " milliseconds." << std::endl;
             } else if (s->isSet("prctl")) {
                 // Determine which engine is to be used to choose the right model checker.
 				LOG4CPLUS_DEBUG(logger, s->getOptionByLongName("matrixLibrary").getArgument(0).getValueAsString());
@@ -571,6 +604,9 @@ int main(const int argc, const char* argv[]) {
 				// Depending on the model type, the appropriate model checking procedure is chosen.
 				storm::modelchecker::prctl::AbstractModelChecker<double>* modelchecker = nullptr;
                 
+				// Modelchecking Time Measurement, Start
+				std::chrono::high_resolution_clock::time_point modelcheckingStart = std::chrono::high_resolution_clock::now();
+
 				switch (model->getType()) {
                     case storm::models::DTMC:
                         LOG4CPLUS_INFO(logger, "Model is a DTMC.");
@@ -602,8 +638,16 @@ int main(const int argc, const char* argv[]) {
 				if (modelchecker != nullptr) {
 					delete modelchecker;
 				}
+
+				// Modelchecking Time Measurement, End
+				std::chrono::high_resolution_clock::time_point modelcheckingEnd = std::chrono::high_resolution_clock::now();
+				std::cout << "Running the PRCTL ModelChecker took " << std::chrono::duration_cast<std::chrono::milliseconds>(modelcheckingEnd - modelcheckingStart).count() << " milliseconds." << std::endl;
             }
         }
+
+		// Execution Time Measurement, End
+		std::chrono::high_resolution_clock::time_point executionEnd = std::chrono::high_resolution_clock::now();
+		std::cout << "Complete execution took " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEnd - executionStart).count() << " milliseconds." << std::endl;
         
         // Perform clean-up and terminate.
 		cleanUp();

From 28eed65a0dbf103ed548eada8cff1a1f664923d6 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 6 Jun 2014 11:41:56 +0200
Subject: [PATCH 137/147] Fixed a reference to a non-existant option.

Former-commit-id: 02020513cc44120cc0580db2ae08a36638636856
---
 src/storm.cpp | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/storm.cpp b/src/storm.cpp
index db3f233fb..8d3810f72 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -31,6 +31,7 @@
 #include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
 #include "src/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
 #include "src/solver/GmmxxLinearEquationSolver.h"
+#include "src/solver/NativeLinearEquationSolver.h"
 #include "src/solver/GmmxxNondeterministicLinearEquationSolver.h"
 #include "src/solver/GurobiLpSolver.h"
 #include "src/counterexamples/MILPMinimalLabelSetGenerator.h"
@@ -252,10 +253,12 @@ void cleanUp() {
 storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Dtmc<double> const & dtmc) {
     // Create the appropriate model checker.
 	storm::settings::Settings* s = storm::settings::Settings::getInstance();
-	std::string const chosenMatrixLibrary = s->getOptionByLongName("matrixLibrary").getArgument(0).getValueAsString();
-	if (chosenMatrixLibrary == "gmm++") {
+	std::string const& linsolver = s->getOptionByLongName("linsolver").getArgument(0).getValueAsString();
+	if (linsolver == "gmm++") {
 		return new storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double>(dtmc, new storm::solver::GmmxxLinearEquationSolver<double>());
-	}
+	} else if (linsolver == "native") {
+		return new storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double>(dtmc, new storm::solver::NativeLinearEquationSolver<double>());
+    }
     
 	// The control flow should never reach this point, as there is a default setting for matrixlib.
 	std::string message = "No matrix library suitable for DTMC model checking has been set.";
@@ -493,9 +496,6 @@ int main(const int argc, const char* argv[]) {
 				std::chrono::high_resolution_clock::time_point counterexampleEnd = std::chrono::high_resolution_clock::now();
 				std::cout << "Generating the counterexample took " << std::chrono::duration_cast<std::chrono::milliseconds>(counterexampleEnd - counterexampleStart).count() << " milliseconds." << std::endl;
 			} else {
-				// Determine which engine is to be used to choose the right model checker.
-				LOG4CPLUS_DEBUG(logger, s->getOptionByLongName("matrixLibrary").getArgument(0).getValueAsString());
-
 				// Depending on the model type, the appropriate model checking procedure is chosen.
 				storm::modelchecker::prctl::AbstractModelChecker<double>* modelchecker = nullptr;
 				model->printModelInformationToStream(std::cout);
@@ -598,9 +598,6 @@ int main(const int argc, const char* argv[]) {
 				std::chrono::high_resolution_clock::time_point minCmdEnd = std::chrono::high_resolution_clock::now();
 				std::cout << "Minimal command Counterexample generation took " << std::chrono::duration_cast<std::chrono::milliseconds>(minCmdStart - minCmdEnd).count() << " milliseconds." << std::endl;
             } else if (s->isSet("prctl")) {
-                // Determine which engine is to be used to choose the right model checker.
-				LOG4CPLUS_DEBUG(logger, s->getOptionByLongName("matrixLibrary").getArgument(0).getValueAsString());
-                
 				// Depending on the model type, the appropriate model checking procedure is chosen.
 				storm::modelchecker::prctl::AbstractModelChecker<double>* modelchecker = nullptr;
                 

From 478f5ee38c8048d0261f5649930256e309d2a655 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 6 Jun 2014 15:14:14 +0200
Subject: [PATCH 138/147] Started separating expression parsing from PRISM
 model parsing.

Former-commit-id: 84d1354f9726b4200a79a0e30d9c05b26e118ab4
---
 src/parser/ExpressionParser.cpp      | 382 ++++++++++++++++++++++++++
 src/parser/ExpressionParser.h        | 126 +++++++++
 src/parser/PrismParser.cpp           | 383 ++-------------------------
 src/parser/PrismParser.h             |  82 +-----
 src/parser/SpiritParserDefinitions.h |  21 ++
 5 files changed, 549 insertions(+), 445 deletions(-)
 create mode 100644 src/parser/ExpressionParser.cpp
 create mode 100644 src/parser/ExpressionParser.h
 create mode 100644 src/parser/SpiritParserDefinitions.h

diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp
new file mode 100644
index 000000000..e879994f6
--- /dev/null
+++ b/src/parser/ExpressionParser.cpp
@@ -0,0 +1,382 @@
+#include "src/parser/ExpressionParser.h"
+#include "src/exceptions/InvalidArgumentException.h"
+#include "src/exceptions/InvalidTypeException.h"
+#include "src/exceptions/WrongFormatException.h"
+
+namespace storm {
+    namespace parser {
+        ExpressionParser::ExpressionParser(qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_) : ExpressionParser::base_type(expression), createExpressions(false), acceptDoubleLiterals(true), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
+            identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&ExpressionParser::isValidIdentifier, phoenix::ref(*this), qi::_1)];
+            identifier.name("identifier");
+            
+            floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createFloorExpression, phoenix::ref(*this), qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createCeilExpression, phoenix::ref(*this), qi::_1)]];
+            floorCeilExpression.name("floor/ceil expression");
+            
+            minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMinimumExpression, phoenix::ref(*this), qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createMaximumExpression, phoenix::ref(*this), qi::_1, qi::_2)]];
+            minMaxExpression.name("min/max expression");
+            
+            identifierExpression = identifier[qi::_val = phoenix::bind(&ExpressionParser::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
+            identifierExpression.name("identifier expression");
+            
+            literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&ExpressionParser::createTrueExpression, phoenix::ref(*this))] | qi::lit("false")[qi::_val = phoenix::bind(&ExpressionParser::createFalseExpression, phoenix::ref(*this))] | strict_double[qi::_val = phoenix::bind(&ExpressionParser::createDoubleLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)] | qi::int_[qi::_val = phoenix::bind(&ExpressionParser::createIntegerLiteralExpression, phoenix::ref(*this), qi::_1)];
+            literalExpression.name("literal expression");
+            
+            atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression;
+            atomicExpression.name("atomic expression");
+            
+            unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_1)];
+            unaryExpression.name("unary expression");
+            
+            multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]);
+            multiplicationExpression.name("multiplication expression");
+            
+            plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
+            plusExpression.name("plus expression");
+            
+            relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
+            relativeExpression.name("relative expression");
+            
+            equalityExpression = relativeExpression[qi::_val = qi::_1] >> *((qi::lit("=")[qi::_a = true] | qi::lit("!=")[qi::_a = false]) >> relativeExpression)[phoenix::if_(qi::_a) [ qi::_val = phoenix::bind(&ExpressionParser::createEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] .else_ [ qi::_val = phoenix::bind(&ExpressionParser::createNotEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] ];
+            equalityExpression.name("equality expression");
+            
+            andExpression = equalityExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> equalityExpression)[qi::_val = phoenix::bind(&ExpressionParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
+            andExpression.name("and expression");
+            
+            orExpression = andExpression[qi::_val = qi::_1] >> *((qi::lit("|")[qi::_a = true] | qi::lit("=>")[qi::_a = false]) >> andExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createImpliesExpression, phoenix::ref(*this), qi::_val, qi::_1)] ];
+            orExpression.name("or expression");
+            
+            iteExpression = orExpression[qi::_val = qi::_1] >> -(qi::lit("?") > orExpression > qi::lit(":") > orExpression)[qi::_val = phoenix::bind(&ExpressionParser::createIteExpression, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
+            iteExpression.name("if-then-else expression");
+            
+            expression %= iteExpression;
+            expression.name("expression");
+            
+            // Enable error reporting.
+            qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(iteExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(equalityExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+            qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
+        }
+        
+        void ExpressionParser::setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_) {
+            this->createExpressions = true;
+            this->identifiers_ = identifiers_;
+        }
+        
+        void ExpressionParser::unsetIdentifierMapping() {
+            this->createExpressions = false;
+        }
+        
+        void ExpressionParser::setAcceptDoubleLiterals(bool flag) {
+            this->acceptDoubleLiterals = flag;
+        }
+        
+        storm::expressions::Expression ExpressionParser::createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const {
+            if (this->createExpressions) {
+                try {
+                    return e1.ite(e2, e3);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1.implies(e2);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 || e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try{
+                    return e1 && e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 > e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 >= e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 < e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 <= e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
+                        return e1.iff(e2);
+                    } else {
+                        return e1 == e2;
+                    }
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
+                        return e1 ^ e2;
+                    } else {
+                        return e1 != e2;
+                    }
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 + e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 - e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 * e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 / e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createNotExpression(storm::expressions::Expression e1) const {
+            if (this->createExpressions) {
+                try {
+                    return !e1;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createMinusExpression(storm::expressions::Expression e1) const {
+            if (this->createExpressions) {
+                try {
+                    return -e1;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createTrueExpression() const {
+            if (this->createExpressions) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::createTrue();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createFalseExpression() const {
+            return storm::expressions::Expression::createFalse();
+        }
+        
+        storm::expressions::Expression ExpressionParser::createDoubleLiteralExpression(double value, bool& pass) const {
+            // If we are not supposed to accept double expressions, we reject it by setting pass to false.
+            if (!this->acceptDoubleLiterals) {
+                pass = false;
+            }
+            
+            if (this->createExpressions) {
+                return storm::expressions::Expression::createDoubleLiteral(value);
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createIntegerLiteralExpression(int value) const {
+            if (this->createExpressions) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                return storm::expressions::Expression::createIntegerLiteral(static_cast<int_fast64_t>(value));
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return storm::expressions::Expression::minimum(e1, e2);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return storm::expressions::Expression::maximum(e1, e2);
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createFloorExpression(storm::expressions::Expression e1) const {
+            if (this->createExpressions) {
+                try {
+                    return e1.floor();
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createCeilExpression(storm::expressions::Expression e1) const {
+            if (this->createExpressions) {
+                try {
+                    return e1.ceil();
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::getIdentifierExpression(std::string const& identifier) const {
+            if (this->createExpressions) {
+                return storm::expressions::Expression::createFalse();
+            } else {
+                storm::expressions::Expression const* expression = this->identifiers_->find(identifier);
+                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'.");
+                return *expression;
+            }
+        }
+        
+        bool ExpressionParser::isValidIdentifier(std::string const& identifier) {
+            if (this->invalidIdentifiers_.find(identifier) != nullptr) {
+                return false;
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/parser/ExpressionParser.h b/src/parser/ExpressionParser.h
new file mode 100644
index 000000000..c340f9c14
--- /dev/null
+++ b/src/parser/ExpressionParser.h
@@ -0,0 +1,126 @@
+#ifndef STORM_PARSER_EXPRESSIONPARSER_H_
+#define	STORM_PARSER_EXPRESSIONPARSER_H_
+
+#include "src/parser/SpiritParserDefinitions.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/exceptions/ExceptionMacros.h"
+#include "src/exceptions/WrongFormatException.h"
+
+namespace storm {
+    namespace parser {
+        class ExpressionParser : public qi::grammar<Iterator, storm::expressions::Expression(), Skipper> {
+        public:
+            /*!
+             * Creates an expression parser. Initially the parser is set to a mode in which it will not generate the
+             * actual expressions but only perform a syntax check and return the expression "false". To make the parser
+             * generate the actual expressions, a mapping of valid identifiers to their expressions need to be provided
+             * later.
+             *
+             * @param invalidIdentifiers_ A symbol table of identifiers that are to be rejected.
+             */
+            ExpressionParser(qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_);
+            
+            /*!
+             * Sets an identifier mapping that is used to determine valid variables in the expression. The mapped-to
+             * expressions will be substituted wherever the key value appears in the parsed expression. After setting
+             * this, the parser will generate expressions.
+             *
+             * @param identifiers A pointer to a mapping from identifiers to expressions.
+             */
+            void setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_);
+            
+            /*!
+             * Unsets a previously set identifier mapping. This will make the parser not generate expressions any more
+             * but merely check for syntactic correctness of an expression.
+             */
+            void unsetIdentifierMapping();
+            
+            /*!
+             * Sets whether double literals are to be accepted or not.
+             *
+             * @param flag If set to true, double literals are accepted.
+             */
+            void setAcceptDoubleLiterals(bool flag);
+            
+        private:
+            // A flag that indicates whether expressions should actually be generated or just a syntax check shall be
+            // performed.
+            bool createExpressions;
+            
+            // A flag that indicates whether double literals are accepted.
+            bool acceptDoubleLiterals;
+            
+            // The currently used mapping of identifiers to expressions. This is used if the parser is set to create
+            // expressions.
+            qi::symbols<char, storm::expressions::Expression> const* identifiers_;
+            
+            // The symbol table of invalid identifiers.
+            qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_;
+            
+            // Rules for parsing a composed expression.
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> iteExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> orExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> equalityExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> identifierExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
+            qi::rule<Iterator, std::string(), Skipper> identifier;
+            
+            // Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
+            boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
+            
+            // Helper functions to create expressions.
+            storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const;
+            storm::expressions::Expression createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createNotExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression createTrueExpression() const;
+            storm::expressions::Expression createFalseExpression() const;
+            storm::expressions::Expression createDoubleLiteralExpression(double value, bool& pass) const;
+            storm::expressions::Expression createIntegerLiteralExpression(int value) const;
+            storm::expressions::Expression createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createFloorExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression createCeilExpression(storm::expressions::Expression e1) const;
+            storm::expressions::Expression getIdentifierExpression(std::string const& identifier) const;
+            
+            bool isValidIdentifier(std::string const& identifier);
+            
+            // Functor used for displaying error information.
+            struct ErrorHandler {
+                typedef qi::error_handler_result result_type;
+                
+                template<typename T1, typename T2, typename T3, typename T4>
+                qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(where) << ": " << " expecting " << what << ".");
+                    return qi::fail;
+                }
+            };
+            
+            // An error handler function.
+            phoenix::function<ErrorHandler> handler;
+        };
+    } // namespace parser
+} // namespace storm
+
+#endif /* STORM_PARSER_EXPRESSIONPARSER_H_ */
\ No newline at end of file
diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index d4686bcff..5e64ca8eb 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -60,53 +60,11 @@ namespace storm {
             return result;
         }
         
-        PrismParser::PrismParser(std::string const& filename, Iterator first) : PrismParser::base_type(start), secondRun(false), allowDoubleLiteralsFlag(true), filename(filename), annotate(first) {
+        PrismParser::PrismParser(std::string const& filename, Iterator first) : PrismParser::base_type(start), secondRun(false), filename(filename), annotate(first), expressionParser(keywords_) {
             // Parse simple identifier.
             identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&PrismParser::isValidIdentifier, phoenix::ref(*this), qi::_1)];
             identifier.name("identifier");
             
-            floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createFloorExpression, phoenix::ref(*this), qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createCeilExpression, phoenix::ref(*this), qi::_1)]];
-            floorCeilExpression.name("floor/ceil expression");
-            
-            minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createMinimumExpression, phoenix::ref(*this), qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMaximumExpression, phoenix::ref(*this), qi::_1, qi::_2)]];
-            minMaxExpression.name("min/max expression");
-            
-            identifierExpression = identifier[qi::_val = phoenix::bind(&PrismParser::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
-            identifierExpression.name("identifier expression");
-            
-            literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&PrismParser::createTrueExpression, phoenix::ref(*this))] | qi::lit("false")[qi::_val = phoenix::bind(&PrismParser::createFalseExpression, phoenix::ref(*this))] | strict_double[qi::_val = phoenix::bind(&PrismParser::createDoubleLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)] | qi::int_[qi::_val = phoenix::bind(&PrismParser::createIntegerLiteralExpression, phoenix::ref(*this), qi::_1)];
-            literalExpression.name("literal expression");
-            
-            atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression;
-            atomicExpression.name("atomic expression");
-            
-            unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = phoenix::bind(&PrismParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_1)];
-            unaryExpression.name("unary expression");
-            
-            multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]);
-            multiplicationExpression.name("multiplication expression");
-            
-            plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
-            plusExpression.name("plus expression");
-            
-            relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
-            relativeExpression.name("relative expression");
-            
-            equalityExpression = relativeExpression[qi::_val = qi::_1] >> *((qi::lit("=")[qi::_a = true] | qi::lit("!=")[qi::_a = false]) >> relativeExpression)[phoenix::if_(qi::_a) [ qi::_val = phoenix::bind(&PrismParser::createEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] .else_ [ qi::_val = phoenix::bind(&PrismParser::createNotEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] ];
-            equalityExpression.name("equality expression");
-            
-            andExpression = equalityExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> equalityExpression)[qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
-            andExpression.name("and expression");
-            
-            orExpression = andExpression[qi::_val = qi::_1] >> *((qi::lit("|")[qi::_a = true] | qi::lit("=>")[qi::_a = false]) >> andExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createImpliesExpression, phoenix::ref(*this), qi::_val, qi::_1)] ];
-            orExpression.name("or expression");
-            
-            iteExpression = orExpression[qi::_val = qi::_1] >> -(qi::lit("?") > orExpression > qi::lit(":") > orExpression)[qi::_val = phoenix::bind(&PrismParser::createIteExpression, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
-            iteExpression.name("if-then-else expression");
-            
-            expression %= iteExpression;
-            expression.name("expression");
-            
             modelTypeDefinition %= modelType_;
             modelTypeDefinition.name("model type");
             
@@ -122,25 +80,25 @@ namespace storm {
             undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition);
             undefinedConstantDefinition.name("undefined constant definition");
             
-            definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)];
+            definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expressionParser > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)];
             definedBooleanConstantDefinition.name("defined boolean constant declaration");
             
-            definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)];
+            definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expressionParser >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)];
             definedIntegerConstantDefinition.name("defined integer constant declaration");
             
-            definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)];
+            definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expressionParser > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)];
             definedDoubleConstantDefinition.name("defined double constant declaration");
             
             definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
             definedConstantDefinition.name("defined constant definition");
             
-            formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expressionParser > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createFormula, phoenix::ref(*this), qi::_1, qi::_2)];
             formulaDefinition.name("formula definition");
             
-            booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)];
+            booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expressionParser) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)];
             booleanVariableDefinition.name("boolean variable definition");
             
-            integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression[qi::_a = qi::_1] > qi::lit("..") > expression > qi::lit("]")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)];
+            integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expressionParser[qi::_a = qi::_1] > qi::lit("..") > expressionParser > qi::lit("]")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expressionParser[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)];
             integerVariableDefinition.name("integer variable definition");
             
             variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]);
@@ -149,10 +107,10 @@ namespace storm {
             globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)]));
             globalVariableDefinition.name("global variable declaration list");
                         
-            stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
+            stateRewardDefinition = (expressionParser > qi::lit(":") > expressionParser >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
             stateRewardDefinition.name("state reward definition");
             
-            transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
+            transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expressionParser > qi::lit(":") > expressionParser > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
             transitionRewardDefinition.name("transition reward definition");
             
             rewardModelDefinition = (qi::lit("rewards") > -(qi::lit("\"") > identifier[qi::_a = qi::_1] > qi::lit("\""))
@@ -162,25 +120,25 @@ namespace storm {
                                      >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismParser::createRewardModel, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
             rewardModelDefinition.name("reward model definition");
             
-            initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesConstruct, phoenix::ref(*this), qi::_1, qi::_r1)];
+            initialStatesConstruct = (qi::lit("init") > expressionParser > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesConstruct, phoenix::ref(*this), qi::_1, qi::_r1)];
             initialStatesConstruct.name("initial construct");
             
-            labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
+            labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expressionParser >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
             labelDefinition.name("label definition");
             
-            assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&PrismParser::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)];
+            assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expressionParser > qi::lit(")"))[qi::_val = phoenix::bind(&PrismParser::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)];
             assignmentDefinition.name("assignment");
             
             assignmentDefinitionList %= +assignmentDefinition % "&";
             assignmentDefinitionList.name("assignment list");
             
-            updateDefinition = (((plusExpression > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismParser::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)];
+            updateDefinition = (((expressionParser > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismParser::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)];
             updateDefinition.name("update");
             
             updateListDefinition %= +updateDefinition(qi::_r1) % "+";
             updateListDefinition.name("update list");
             
-            commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)];
+            commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expressionParser > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)];
             commandDefinition.name("command definition");
             
             moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition(qi::_r1) > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismParser::createModule, phoenix::ref(*this), qi::_1, qi::_a, qi::_b, qi::_2, qi::_r1)];
@@ -209,22 +167,6 @@ namespace storm {
                      > qi::eoi)[qi::_val = phoenix::bind(&PrismParser::createProgram, phoenix::ref(*this), qi::_a)];
             start.name("probabilistic program");
             
-            // Enable error reporting.
-            qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(iteExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(equalityExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            
             // Enable location tracking for important entities.
             auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
             qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction);
@@ -250,7 +192,7 @@ namespace storm {
         }
         
         void PrismParser::allowDoubleLiterals(bool flag) {
-            this->allowDoubleLiteralsFlag = flag;
+            this->expressionParser.setAcceptDoubleLiterals(flag);
         }
         
         std::string const& PrismParser::getFilename() const {
@@ -274,301 +216,6 @@ namespace storm {
             return true;
         }
         
-        storm::expressions::Expression PrismParser::createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1.ite(e2, e3);
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1.implies(e2);
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 || e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try{
-                    return e1 && e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 > e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 >= e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 < e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 <= e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
-                        return e1.iff(e2);
-                    } else {
-                        return e1 == e2;
-                    }
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
-                        return e1 ^ e2;
-                    } else {
-                        return e1 != e2;
-                    }
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 + e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 - e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 * e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1 / e2;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createNotExpression(storm::expressions::Expression e1) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return !e1;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createMinusExpression(storm::expressions::Expression e1) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return -e1;
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createTrueExpression() const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                return storm::expressions::Expression::createTrue();
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createFalseExpression() const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                return storm::expressions::Expression::createFalse();
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createDoubleLiteralExpression(double value, bool& pass) const {
-            // If we are not supposed to accept double expressions, we reject it by setting pass to false.
-            if (!this->allowDoubleLiteralsFlag) {
-                pass = false;
-            }
-            
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                return storm::expressions::Expression::createDoubleLiteral(value);
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createIntegerLiteralExpression(int value) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                return storm::expressions::Expression::createIntegerLiteral(static_cast<int_fast64_t>(value));
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return storm::expressions::Expression::minimum(e1, e2);
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return storm::expressions::Expression::maximum(e1, e2);
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createFloorExpression(storm::expressions::Expression e1) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1.floor();
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::createCeilExpression(storm::expressions::Expression e1) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                try {
-                    return e1.ceil();
-                } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": " << e.what() << ".");
-                }
-            }
-        }
-        
-        storm::expressions::Expression PrismParser::getIdentifierExpression(std::string const& identifier) const {
-            if (!this->secondRun) {
-                return storm::expressions::Expression::createFalse();
-            } else {
-                storm::expressions::Expression const* expression = this->identifiers_.find(identifier);
-                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'.");
-                return *expression;
-            }
-        }
-        
         storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
             if (!this->secondRun) {
                 LOG_THROW(this->identifiers_.find(newConstant) == nullptr, storm::exceptions::WrongFormatException, "Parsing error in " << this->getFilename() << ", line " << get_line(qi::_3) << ": Duplicate identifier '" << newConstant << "'.");
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index e1a9136ba..bdf84af24 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -6,23 +6,8 @@
 #include <memory>
 #include <iomanip>
 
-// Include boost spirit.
-#define BOOST_SPIRIT_USE_PHOENIX_V3
-#include <boost/typeof/typeof.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
-#include <boost/spirit/include/support_line_pos_iterator.hpp>
-#include <boost/spirit/home/classic/iterator/position_iterator.hpp>
-
-namespace qi = boost::spirit::qi;
-namespace phoenix = boost::phoenix;
-
-typedef std::string::const_iterator BaseIteratorType;
-typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType;
-typedef PositionIteratorType Iterator;
-typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
-typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
-
+#include "src/parser/SpiritParserDefinitions.h"
+#include "src/parser/ExpressionParser.h"
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/Expressions.h"
@@ -113,17 +98,6 @@ namespace storm {
                 }
             };
             
-            // Functor used for displaying error information.
-            struct ErrorHandler {
-                typedef qi::error_handler_result result_type;
-                
-                template<typename T1, typename T2, typename T3, typename T4>
-                qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(where) << ": " << " expecting " << what << ".");
-                    return qi::fail;
-                }
-            };
-            
             // Functor used for annotating entities with line number information.
             class PositionAnnotation {
             public:
@@ -165,9 +139,6 @@ namespace storm {
              */
             void allowDoubleLiterals(bool flag);
             
-            // A flag that stores wether to allow or forbid double literals in parsed expressions.
-            bool allowDoubleLiteralsFlag;
-            
             // The name of the file being parsed.
             std::string filename;
             
@@ -179,7 +150,6 @@ namespace storm {
             std::string const& getFilename() const;
             
             // A function used for annotating the entities with their position.
-            phoenix::function<ErrorHandler> handler;
             phoenix::function<PositionAnnotation> annotate;
             
             // The starting point of the grammar.
@@ -237,60 +207,18 @@ namespace storm {
             // Rules for identifier parsing.
             qi::rule<Iterator, std::string(), Skipper> identifier;
             
-            // Rules for parsing a composed expression.
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> iteExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> orExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> equalityExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), Skipper> identifierExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
-            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
-            
-            // Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
-            boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
-            
             // Parsers that recognize special keywords and model types.
             storm::parser::PrismParser::keywordsStruct keywords_;
             storm::parser::PrismParser::modelTypeStruct modelType_;
             qi::symbols<char, storm::expressions::Expression> identifiers_;
             
+            // Parser used for recognizing expressions.
+            storm::parser::ExpressionParser expressionParser;
+            
             // Helper methods used in the grammar.
             bool isValidIdentifier(std::string const& identifier);
             bool addInitialStatesConstruct(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
             
-            storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const;
-            storm::expressions::Expression createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createNotExpression(storm::expressions::Expression e1) const;
-            storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1) const;
-            storm::expressions::Expression createTrueExpression() const;
-            storm::expressions::Expression createFalseExpression() const;
-            storm::expressions::Expression createDoubleLiteralExpression(double value, bool& pass) const;
-            storm::expressions::Expression createIntegerLiteralExpression(int value) const;
-            storm::expressions::Expression createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
-            storm::expressions::Expression createFloorExpression(storm::expressions::Expression e1) const;
-            storm::expressions::Expression createCeilExpression(storm::expressions::Expression e1) const;
-            storm::expressions::Expression getIdentifierExpression(std::string const& identifier) const;
-            
             storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
             storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
             storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
diff --git a/src/parser/SpiritParserDefinitions.h b/src/parser/SpiritParserDefinitions.h
new file mode 100644
index 000000000..feb78f77d
--- /dev/null
+++ b/src/parser/SpiritParserDefinitions.h
@@ -0,0 +1,21 @@
+#ifndef STORM_PARSER_SPIRITPARSERDEFINITIONS_H_
+#define	STORM_PARSER_SPIRITPARSERDEFINITIONS_H_
+
+// Include boost spirit.
+#define BOOST_SPIRIT_USE_PHOENIX_V3
+#include <boost/typeof/typeof.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/spirit/include/support_line_pos_iterator.hpp>
+#include <boost/spirit/home/classic/iterator/position_iterator.hpp>
+
+namespace qi = boost::spirit::qi;
+namespace phoenix = boost::phoenix;
+
+typedef std::string::const_iterator BaseIteratorType;
+typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType;
+typedef PositionIteratorType Iterator;
+
+typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
+
+#endif /* STORM_PARSER_SPIRITPARSERDEFINITIONS_H_ */
\ No newline at end of file

From 72cc5f2188501724d389daa9510b52cef388713d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 6 Jun 2014 17:04:17 +0200
Subject: [PATCH 139/147] Added 'power' as a binary operator in expression
 classes and expression grammar.

Former-commit-id: c58321709e6e571ffb072f89c184ac46322f54f3
---
 src/parser/ExpressionParser.cpp               | 82 +++++++++++--------
 src/parser/ExpressionParser.h                 |  2 +
 src/parser/PrismParser.cpp                    |  1 +
 .../BinaryNumericalFunctionExpression.cpp     |  5 ++
 .../BinaryNumericalFunctionExpression.h       |  2 +-
 src/storage/expressions/Expression.cpp        | 12 ++-
 src/storage/expressions/OperatorType.h        |  1 +
 test/functional/parser/PrismParserTest.cpp    |  1 +
 test/functional/storage/ExpressionTest.cpp    | 12 ++-
 9 files changed, 78 insertions(+), 40 deletions(-)

diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp
index e879994f6..bb143a2c0 100644
--- a/src/parser/ExpressionParser.cpp
+++ b/src/parser/ExpressionParser.cpp
@@ -27,7 +27,10 @@ namespace storm {
             unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_1)];
             unaryExpression.name("unary expression");
             
-            multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]);
+            powerExpression = unaryExpression[qi::_val = qi::_1] >> -(qi::lit("^") > expression)[qi::_val = phoenix::bind(&ExpressionParser::createPowerExpression, phoenix::ref(*this), qi::_val, qi::_1)];
+            powerExpression.name("power expression");
+            
+            multiplicationExpression = powerExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> powerExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]);
             multiplicationExpression.name("multiplication expression");
             
             plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
@@ -69,12 +72,18 @@ namespace storm {
         }
         
         void ExpressionParser::setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_) {
-            this->createExpressions = true;
-            this->identifiers_ = identifiers_;
+            if (identifiers_ != nullptr) {
+                this->createExpressions = true;
+                this->identifiers_ = identifiers_;
+            } else {
+                this->createExpressions = false;
+                this->identifiers_ = nullptr;
+            }
         }
         
         void ExpressionParser::unsetIdentifierMapping() {
             this->createExpressions = false;
+            this->identifiers_ = nullptr;
         }
         
         void ExpressionParser::setAcceptDoubleLiterals(bool flag) {
@@ -86,7 +95,7 @@ namespace storm {
                 try {
                     return e1.ite(e2, e3);
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -98,7 +107,7 @@ namespace storm {
                 try {
                     return e1.implies(e2);
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -110,7 +119,7 @@ namespace storm {
                 try {
                     return e1 || e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -122,7 +131,7 @@ namespace storm {
                 try{
                     return e1 && e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -134,7 +143,7 @@ namespace storm {
                 try {
                     return e1 > e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -146,7 +155,7 @@ namespace storm {
                 try {
                     return e1 >= e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -158,7 +167,7 @@ namespace storm {
                 try {
                     return e1 < e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -170,7 +179,7 @@ namespace storm {
                 try {
                     return e1 <= e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -186,7 +195,7 @@ namespace storm {
                         return e1 == e2;
                     }
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -196,13 +205,9 @@ namespace storm {
         storm::expressions::Expression ExpressionParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
             if (this->createExpressions) {
                 try {
-                    if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
-                        return e1 ^ e2;
-                    } else {
-                        return e1 != e2;
-                    }
+                    return e1 != e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -214,7 +219,7 @@ namespace storm {
                 try {
                     return e1 + e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -226,7 +231,7 @@ namespace storm {
                 try {
                     return e1 - e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -238,7 +243,19 @@ namespace storm {
                 try {
                     return e1 * e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
+                }
+            } else {
+                return storm::expressions::Expression::createFalse();
+            }
+        }
+        
+        storm::expressions::Expression ExpressionParser::createPowerExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
+            if (this->createExpressions) {
+                try {
+                    return e1 ^ e2;
+                } catch (storm::exceptions::InvalidTypeException const& e) {
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -250,7 +267,7 @@ namespace storm {
                 try {
                     return e1 / e2;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -262,7 +279,7 @@ namespace storm {
                 try {
                     return !e1;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -274,7 +291,7 @@ namespace storm {
                 try {
                     return -e1;
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -308,9 +325,9 @@ namespace storm {
         
         storm::expressions::Expression ExpressionParser::createIntegerLiteralExpression(int value) const {
             if (this->createExpressions) {
-                return storm::expressions::Expression::createFalse();
-            } else {
                 return storm::expressions::Expression::createIntegerLiteral(static_cast<int_fast64_t>(value));
+            } else {
+                return storm::expressions::Expression::createFalse();
             }
         }
         
@@ -319,7 +336,7 @@ namespace storm {
                 try {
                     return storm::expressions::Expression::minimum(e1, e2);
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -331,7 +348,7 @@ namespace storm {
                 try {
                     return storm::expressions::Expression::maximum(e1, e2);
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -343,7 +360,7 @@ namespace storm {
                 try {
                     return e1.floor();
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -355,7 +372,7 @@ namespace storm {
                 try {
                     return e1.ceil();
                 } catch (storm::exceptions::InvalidTypeException const& e) {
-                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << ".");
+                    LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
                 }
             } else {
                 return storm::expressions::Expression::createFalse();
@@ -364,11 +381,12 @@ namespace storm {
         
         storm::expressions::Expression ExpressionParser::getIdentifierExpression(std::string const& identifier) const {
             if (this->createExpressions) {
-                return storm::expressions::Expression::createFalse();
-            } else {
+                LOG_THROW(this->identifiers_ != nullptr, storm::exceptions::WrongFormatException, "Unable to substitute identifier expressions without given mapping.");
                 storm::expressions::Expression const* expression = this->identifiers_->find(identifier);
                 LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'.");
                 return *expression;
+            } else {
+                return storm::expressions::Expression::createFalse();
             }
         }
         
diff --git a/src/parser/ExpressionParser.h b/src/parser/ExpressionParser.h
index c340f9c14..380644caf 100644
--- a/src/parser/ExpressionParser.h
+++ b/src/parser/ExpressionParser.h
@@ -66,6 +66,7 @@ namespace storm {
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> equalityExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
             qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
+            qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> powerExpression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
             qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
@@ -91,6 +92,7 @@ namespace storm {
             storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
+            storm::expressions::Expression createPowerExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
             storm::expressions::Expression createNotExpression(storm::expressions::Expression e1) const;
             storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1) const;
diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 5e64ca8eb..b026880d3 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -189,6 +189,7 @@ namespace storm {
         
         void PrismParser::moveToSecondRun() {
             this->secondRun = true;
+            this->expressionParser.setIdentifierMapping(&this->identifiers_);
         }
         
         void PrismParser::allowDoubleLiterals(bool flag) {
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
index f6172821d..7db4fa0cf 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -1,4 +1,5 @@
 #include <algorithm>
+#include <cmath>
 
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/exceptions/ExceptionMacros.h"
@@ -22,6 +23,7 @@ namespace storm {
                 case OperatorType::Divide: return storm::expressions::OperatorType::Divide; break;
                 case OperatorType::Min: return storm::expressions::OperatorType::Min; break;
                 case OperatorType::Max: return storm::expressions::OperatorType::Max; break;
+                case OperatorType::Power: return storm::expressions::OperatorType::Power; break;
             }
         }
         
@@ -37,6 +39,7 @@ namespace storm {
                 case OperatorType::Divide: return firstOperandEvaluation / secondOperandEvaluation; break;
                 case OperatorType::Min: return std::min(firstOperandEvaluation, secondOperandEvaluation); break;
                 case OperatorType::Max: return std::max(firstOperandEvaluation, secondOperandEvaluation); break;
+                case OperatorType::Power: return static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break;
             }
         }
         
@@ -52,6 +55,7 @@ namespace storm {
                 case OperatorType::Divide: return static_cast<double>(firstOperandEvaluation / secondOperandEvaluation); break;
                 case OperatorType::Min: return static_cast<double>(std::min(firstOperandEvaluation, secondOperandEvaluation)); break;
                 case OperatorType::Max: return static_cast<double>(std::max(firstOperandEvaluation, secondOperandEvaluation)); break;
+                case OperatorType::Power: return std::pow(firstOperandEvaluation, secondOperandEvaluation); break;
             }
         }
         
@@ -79,6 +83,7 @@ namespace storm {
                 case OperatorType::Divide: stream << *this->getFirstOperand() << " / " << *this->getSecondOperand(); break;
                 case OperatorType::Min: stream << "min(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break;
                 case OperatorType::Max: stream << "max(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break;
+                case OperatorType::Power: stream << *this->getFirstOperand() << " ^ " << *this->getSecondOperand(); break;
             }
             stream << ")";
         }
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h
index 13ee489df..77b8021a4 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.h
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h
@@ -11,7 +11,7 @@ namespace storm {
             /*!
              * An enum type specifying the different operators applicable.
              */
-            enum class OperatorType {Plus, Minus, Times, Divide, Min, Max};
+            enum class OperatorType {Plus, Minus, Times, Divide, Min, Max, Power};
             
             /*!
              * Constructs a binary numerical function expression with the given return type, operands and operator.
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index e8de2af62..2c247f796 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -196,8 +196,8 @@ namespace storm {
         }
         
         Expression Expression::operator^(Expression const& other) const {
-            LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '^' requires boolean operands.");
-            return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Xor)));
+            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '^' requires numerical operands.");
+            return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Power)));
         }
         
         Expression Expression::operator&&(Expression const& other) const {
@@ -221,8 +221,12 @@ namespace storm {
         }
         
         Expression Expression::operator!=(Expression const& other) const {
-            LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '!=' requires numerical operands.");
-            return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::NotEqual)));
+            LOG_THROW((this->hasNumericalReturnType() && other.hasNumericalReturnType()) || (this->hasBooleanReturnType() && other.hasBooleanReturnType()), storm::exceptions::InvalidTypeException, "Operator '!=' requires operands of equal type.");
+            if (this->hasNumericalReturnType() && other.hasNumericalReturnType()) {
+                return Expression(std::shared_ptr<BaseExpression>(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::NotEqual)));
+            } else {
+                return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Xor)));
+            }
         }
         
         Expression Expression::operator>(Expression const& other) const {
diff --git a/src/storage/expressions/OperatorType.h b/src/storage/expressions/OperatorType.h
index 8a4f199aa..8968cf105 100644
--- a/src/storage/expressions/OperatorType.h
+++ b/src/storage/expressions/OperatorType.h
@@ -16,6 +16,7 @@ namespace storm {
             Divide,
             Min,
             Max,
+            Power,
             Equal,
             NotEqual,
             Less,
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index 5bf7bfd49..3621149b8 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -4,6 +4,7 @@
 
 TEST(PrismParser, StandardModelTest) {
     storm::prism::Program result;
+    result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm");
     EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm"));
     EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm"));
     EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm"));
diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp
index d3a920d1d..642456995 100644
--- a/test/functional/storage/ExpressionTest.cpp
+++ b/test/functional/storage/ExpressionTest.cpp
@@ -223,10 +223,10 @@ TEST(Expression, OperatorTest) {
     ASSERT_NO_THROW(tempExpression = boolVarExpression.iff(boolVarExpression));
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
-    ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException);
-    ASSERT_NO_THROW(tempExpression = trueExpression ^ falseExpression);
+    ASSERT_THROW(tempExpression = trueExpression != piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = trueExpression != falseExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
-    ASSERT_NO_THROW(tempExpression = boolVarExpression ^ boolVarExpression);
+    ASSERT_NO_THROW(tempExpression = boolVarExpression != boolVarExpression);
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool);
     
     ASSERT_THROW(tempExpression = trueExpression.floor(), storm::exceptions::InvalidTypeException);
@@ -240,6 +240,12 @@ TEST(Expression, OperatorTest) {
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
     ASSERT_NO_THROW(tempExpression = doubleVarExpression.ceil());
     EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+
+    ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException);
+    ASSERT_NO_THROW(tempExpression = threeExpression ^ threeExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int);
+    ASSERT_NO_THROW(tempExpression = intVarExpression ^ doubleVarExpression);
+    EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double);
 }
 
 TEST(Expression, SubstitutionTest) {

From dd73387ed1b6618e0a571709aae4ba6f5a8ce734 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 6 Jun 2014 19:30:40 +0200
Subject: [PATCH 140/147] Add missing case.

Former-commit-id: b30aa3bc0d5af7c8edb2f7f04315bf25bdad22ce
---
 src/storage/expressions/LinearityCheckVisitor.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/storage/expressions/LinearityCheckVisitor.cpp b/src/storage/expressions/LinearityCheckVisitor.cpp
index 9b382ed22..6f595900a 100644
--- a/src/storage/expressions/LinearityCheckVisitor.cpp
+++ b/src/storage/expressions/LinearityCheckVisitor.cpp
@@ -73,6 +73,7 @@ namespace storm {
                     break;
                 case BinaryNumericalFunctionExpression::OperatorType::Min: resultStack.push(LinearityStatus::NonLinear); break;
                 case BinaryNumericalFunctionExpression::OperatorType::Max: resultStack.push(LinearityStatus::NonLinear); break;
+                case BinaryNumericalFunctionExpression::OperatorType::Power: resultStack.push(LinearityStatus::NonLinear); break;
             }
         }
         

From 5d53c6efa5d091c7054d1f79befc7129489af9e5 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 15 Jun 2014 17:56:46 +0200
Subject: [PATCH 141/147] Added ODD-concept to easily convert between DD-based
 and explicit formats.

Former-commit-id: f2a2a002b77727d81d348c133348944d4b71b2b9
---
 src/storage/dd/CuddDd.cpp              |  50 ++++++++++
 src/storage/dd/CuddDd.h                |  48 +++++++++-
 src/storage/dd/CuddDdManager.h         |   1 +
 src/storage/dd/CuddDdMetaVariable.h    |   4 +-
 src/storage/dd/CuddOdd.cpp             |  97 +++++++++++++++++++
 src/storage/dd/CuddOdd.h               | 123 +++++++++++++++++++++++++
 src/storage/dd/Odd.h                   |  13 +++
 test/functional/storage/CuddDdTest.cpp |  17 ++++
 8 files changed, 351 insertions(+), 2 deletions(-)
 create mode 100644 src/storage/dd/CuddOdd.cpp
 create mode 100644 src/storage/dd/CuddOdd.h
 create mode 100644 src/storage/dd/Odd.h

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index f02e0d7a1..a7d9df2d1 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -2,6 +2,7 @@
 #include <algorithm>
 
 #include "src/storage/dd/CuddDd.h"
+#include "src/storage/dd/CuddOdd.h"
 #include "src/storage/dd/CuddDdManager.h"
 
 #include "src/exceptions/InvalidArgumentException.h"
@@ -425,6 +426,55 @@ namespace storm {
             return Cudd_IsConstant(this->cuddAdd.getNode());
         }
         
+        uint_fast64_t Dd<DdType::CUDD>::getIndex() const {
+            return static_cast<uint_fast64_t>(this->getCuddAdd().NodeReadIndex());
+        }
+        
+        std::vector<double> Dd<DdType::CUDD>::toDoubleVector() const {
+            return this->toDoubleVector(Odd<DdType::CUDD>(*this));
+        }
+        
+        std::vector<double> Dd<DdType::CUDD>::toDoubleVector(Odd<DdType::CUDD> const& odd) const {
+            std::vector<double> result(odd.getTotalOffset());
+            std::vector<uint_fast64_t> ddVariableIndices = this->getSortedVariableIndices();
+            toDoubleVectorRec(this->getCuddAdd().getNode(), result, odd, 0, ddVariableIndices.size(), 0, ddVariableIndices);
+            return result;
+        }
+        
+        void Dd<DdType::CUDD>::toDoubleVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const {
+            if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
+                return;
+            }
+            
+            // If we are at the maximal level, the value to be set is stored as a constant in the DD.
+            if (currentLevel == maxLevel) {
+                result[currentOffset] = Cudd_V(dd);
+            } else if (ddVariableIndices[currentLevel] < dd->index) {
+                // If we skipped a level, we need to enumerate the explicit entries for the case in which the bit is set
+                // and for the one in which it is not set.
+                toDoubleVectorRec(dd, result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
+                toDoubleVectorRec(dd, result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
+            } else {
+                // Otherwise, we simply recursively call the function for both (different) cases.
+                toDoubleVectorRec(Cudd_E(dd), result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
+                toDoubleVectorRec(Cudd_T(dd), result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
+            }
+        }
+        
+        std::vector<uint_fast64_t> Dd<DdType::CUDD>::getSortedVariableIndices() const {
+            std::vector<uint_fast64_t> ddVariableIndices;
+            for (auto const& metaVariableName : this->getContainedMetaVariableNames()) {
+                auto const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
+                for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                    ddVariableIndices.push_back(ddVariable.getIndex());
+                }
+            }
+            
+            // Next, we need to sort them, since they may be arbitrarily ordered otherwise.
+            std::sort(ddVariableIndices.begin(), ddVariableIndices.end());
+            return ddVariableIndices;
+        }
+        
         bool Dd<DdType::CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
             auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
             return metaVariable != containedMetaVariableNames.end();
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index b269c4dfd..a7951cfb3 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -16,8 +16,9 @@
 
 namespace storm {
     namespace dd {
-        // Forward-declare the DdManager class.
+        // Forward-declare some classes.
         template<DdType Type> class DdManager;
+        template<DdType Type> class Odd;
         
         template<>
         class Dd<DdType::CUDD> {
@@ -25,6 +26,7 @@ namespace storm {
             // Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
             friend class DdManager<DdType::CUDD>;
             friend class DdForwardIterator<DdType::CUDD>;
+            friend class Odd<DdType::CUDD>;
             
             // Instantiate all copy/move constructors/assignments with the default implementation.
             Dd() = default;
@@ -447,6 +449,28 @@ namespace storm {
              */
             bool isConstant() const;
             
+            /*!
+             * Retrieves the index of the topmost variable in the DD.
+             *
+             * @return The index of the topmost variable in DD.
+             */
+            uint_fast64_t getIndex() const;
+            
+            /*!
+             * Converts the DD to a double vector.
+             *
+             * @return The double vector that is represented by this DD.
+             */
+            std::vector<double> toDoubleVector() const;
+            
+            /*!
+             * Converts the DD to a double vector using the given ODD (that needs to be constructed for the DD).
+             *
+             * @param odd The ODD for the DD.
+             * @return The double vector that is represented by this DD.
+             */
+            std::vector<double> toDoubleVector(Odd<DdType::CUDD> const& odd) const;
+            
             /*!
              * Retrieves whether the given meta variable is contained in the DD.
              *
@@ -587,6 +611,28 @@ namespace storm {
              */
             Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
             
+            /*!
+             * Helper function to convert the DD into a double vector.
+             *
+             * @param dd The DD to convert.
+             * @param result The resulting vector whose entries are to be set appropriately. This vector needs to be
+             * preallocated.
+             * @param odd The ODD used for the translation.
+             * @param currentLevel The currently considered level in the DD.
+             * @param maxLevel The number of levels that need to be considered.
+             * @param currentOffset The current offset.
+             * @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
+             */
+            void toDoubleVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const;
+            
+            /*!
+             * Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
+             * because they could be "don't cares"). Additionally, the indices are sorted to allow for easy access.
+             *
+             * @return The (sorted) indices of all DD variables that are contained in this DD.
+             */
+            std::vector<uint_fast64_t> getSortedVariableIndices() const;
+            
             // A pointer to the manager responsible for this DD.
             std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
             
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index a570224c3..75c6a23de 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -16,6 +16,7 @@ namespace storm {
         class DdManager<DdType::CUDD> : public std::enable_shared_from_this<DdManager<DdType::CUDD>> {
         public:
             friend class Dd<DdType::CUDD>;
+            friend class Odd<DdType::CUDD>;
             friend class DdForwardIterator<DdType::CUDD>;
             
             /*!
diff --git a/src/storage/dd/CuddDdMetaVariable.h b/src/storage/dd/CuddDdMetaVariable.h
index b54ca1939..25375dc4d 100644
--- a/src/storage/dd/CuddDdMetaVariable.h
+++ b/src/storage/dd/CuddDdMetaVariable.h
@@ -13,8 +13,9 @@
 
 namespace storm {
     namespace dd {
-        // Forward-declare the DdManager class.
+        // Forward-declare some classes.
         template<DdType Type> class DdManager;
+        template<DdType Type> class Odd;
         
         template<>
         class DdMetaVariable<DdType::CUDD> {
@@ -22,6 +23,7 @@ namespace storm {
             // Declare the DdManager class as friend so it can access the internals of a meta variable.
             friend class DdManager<DdType::CUDD>;
             friend class Dd<DdType::CUDD>;
+            friend class Odd<DdType::CUDD>;
             friend class DdForwardIterator<DdType::CUDD>;
             
             // An enumeration for all legal types of meta variables.
diff --git a/src/storage/dd/CuddOdd.cpp b/src/storage/dd/CuddOdd.cpp
new file mode 100644
index 000000000..3f97dc861
--- /dev/null
+++ b/src/storage/dd/CuddOdd.cpp
@@ -0,0 +1,97 @@
+#include "src/storage/dd/CuddOdd.h"
+
+#include <algorithm>
+
+#include "src/storage/dd/CuddDdManager.h"
+#include "src/storage/dd/CuddDdMetaVariable.h"
+
+namespace storm {
+    namespace dd {
+        Odd<DdType::CUDD>::Odd(Dd<DdType::CUDD> const& dd) {
+            std::shared_ptr<DdManager<DdType::CUDD>> manager = dd.getDdManager();
+            
+            // First, we need to determine the involved DD variables indices.
+            std::vector<uint_fast64_t> ddVariableIndices = dd.getSortedVariableIndices();
+            
+            // Prepare a unique table for each level that keeps the constructed ODD nodes unique.
+            std::vector<std::map<DdNode*, std::shared_ptr<Odd<DdType::CUDD>>>> uniqueTableForLevels(ddVariableIndices.size() + 1);
+            
+            // Now construct the ODD structure.
+            std::shared_ptr<Odd<DdType::CUDD>> rootOdd = buildOddRec(dd.getCuddAdd().getNode(), manager->getCuddManager(), 0, ddVariableIndices.size(), ddVariableIndices, uniqueTableForLevels);
+            
+            // Finally, move the children of the root ODD into this ODD.
+            this->dd = rootOdd->dd;
+            this->elseNode = std::move(rootOdd->elseNode);
+            this->thenNode = std::move(rootOdd->thenNode);
+            this->elseOffset = rootOdd->elseOffset;
+            this->thenOffset = rootOdd->thenOffset;
+        }
+        
+        Odd<DdType::CUDD>::Odd(ADD dd, std::shared_ptr<Odd<DdType::CUDD>>&& elseNode, uint_fast64_t elseOffset, std::shared_ptr<Odd<DdType::CUDD>>&& thenNode, uint_fast64_t thenOffset) : dd(dd), elseNode(elseNode), thenNode(thenNode), elseOffset(elseOffset), thenOffset(thenOffset) {
+            // Intentionally left empty.
+        }
+        
+        Odd<DdType::CUDD> const& Odd<DdType::CUDD>::getThenSuccessor() const {
+            return *this->thenNode;
+        }
+        
+        Odd<DdType::CUDD> const& Odd<DdType::CUDD>::getElseSuccessor() const {
+            return *this->elseNode;
+        }
+        
+        uint_fast64_t Odd<DdType::CUDD>::getElseOffset() const {
+            return this->elseOffset;
+        }
+        
+        void Odd<DdType::CUDD>::setElseOffset(uint_fast64_t newOffset) {
+            this->elseOffset = newOffset;
+        }
+        
+        uint_fast64_t Odd<DdType::CUDD>::getThenOffset() const {
+            return this->thenOffset;
+        }
+        
+        void Odd<DdType::CUDD>::setThenOffset(uint_fast64_t newOffset) {
+            this->thenOffset = newOffset;
+        }
+        
+        uint_fast64_t Odd<DdType::CUDD>::getTotalOffset() const {
+            return this->elseOffset + this->thenOffset;
+        }
+        
+        std::shared_ptr<Odd<DdType::CUDD>> Odd<DdType::CUDD>::buildOddRec(DdNode* dd, Cudd const& manager, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<std::map<DdNode*, std::shared_ptr<Odd<DdType::CUDD>>>>& uniqueTableForLevels) {
+            // Check whether the ODD for this node has already been computed (for this level) and if so, return this instead.
+            auto const& iterator = uniqueTableForLevels[currentLevel].find(dd);
+            if (iterator != uniqueTableForLevels[currentLevel].end()) {
+                return iterator->second;
+            } else {
+                // Otherwise, we need to recursively compute the ODD.
+                
+                // If we are already past the maximal level that is to be considered, we can simply create a Odd without
+                // successors
+                if (currentLevel == maxLevel) {
+                    uint_fast64_t elseOffset = 0;
+                    uint_fast64_t thenOffset = 0;
+                    
+                    // If the DD is not the zero leaf, then the then-offset is 1.
+                    if (dd != Cudd_ReadZero(manager.getManager())) {
+                        thenOffset = 1;
+                    }
+                    
+                    return std::shared_ptr<Odd<DdType::CUDD>>(new Odd<DdType::CUDD>(ADD(manager, dd), nullptr, elseOffset, nullptr, thenOffset));
+                } else if (ddVariableIndices[currentLevel] < static_cast<uint_fast64_t>(dd->index)) {
+                    // If we skipped the level in the DD, we compute the ODD just for the else-successor and use the same
+                    // node for the then-successor as well.
+                    std::shared_ptr<Odd<DdType::CUDD>> elseNode = buildOddRec(dd, manager, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
+                    std::shared_ptr<Odd<DdType::CUDD>> thenNode = elseNode;
+                    return std::shared_ptr<Odd<DdType::CUDD>>(new Odd<DdType::CUDD>(ADD(manager, dd), std::move(elseNode), elseNode->getElseOffset() + elseNode->getThenOffset(), std::move(thenNode), thenNode->getElseOffset() + thenNode->getThenOffset()));
+                } else {
+                    // Otherwise, we compute the ODDs for both the then- and else successors.
+                    std::shared_ptr<Odd<DdType::CUDD>> elseNode = buildOddRec(Cudd_E(dd), manager, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
+                    std::shared_ptr<Odd<DdType::CUDD>> thenNode = buildOddRec(Cudd_T(dd), manager, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
+                    return std::shared_ptr<Odd<DdType::CUDD>>(new Odd<DdType::CUDD>(ADD(manager, dd), std::move(elseNode), elseNode->getElseOffset() + elseNode->getThenOffset(), std::move(thenNode), thenNode->getElseOffset() + thenNode->getThenOffset()));
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dd/CuddOdd.h b/src/storage/dd/CuddOdd.h
new file mode 100644
index 000000000..2927bfde6
--- /dev/null
+++ b/src/storage/dd/CuddOdd.h
@@ -0,0 +1,123 @@
+#ifndef STORM_STORAGE_DD_CUDDODD_H_
+#define STORM_STORAGE_DD_CUDDODD_H_
+
+#include <memory>
+
+#include "src/storage/dd/Odd.h"
+#include "src/storage/dd/CuddDd.h"
+#include "src/utility/OsDetection.h"
+
+// Include the C++-interface of CUDD.
+#include "cuddObj.hh"
+
+namespace storm {
+    namespace dd {
+        template<>
+        class Odd<DdType::CUDD> {
+        public:
+            /*!
+             * Constructs an offset-labeled DD from the given DD.
+             *
+             * @param dd The DD for which to build the offset-labeled DD.
+             */
+            Odd(Dd<DdType::CUDD> const& dd);
+            
+            // Instantiate all copy/move constructors/assignments with the default implementation.
+            Odd() = default;
+            Odd(Odd<DdType::CUDD> const& other) = default;
+			Odd& operator=(Odd<DdType::CUDD> const& other) = default;
+#ifndef WINDOWS
+            Odd(Odd<DdType::CUDD>&& other) = default;
+            Odd& operator=(Odd<DdType::CUDD>&& other) = default;
+#endif
+            
+            /*!
+             * Retrieves the then-successor of this ODD node.
+             *
+             * @return The then-successor of this ODD node.
+             */
+            Odd<DdType::CUDD> const& getThenSuccessor() const;
+
+            /*!
+             * Retrieves the else-successor of this ODD node.
+             *
+             * @return The else-successor of this ODD node.
+             */
+            Odd<DdType::CUDD> const& getElseSuccessor() const;
+
+            /*!
+             * Retrieves the else-offset of this ODD node.
+             *
+             * @return The else-offset of this ODD node.
+             */
+            uint_fast64_t getElseOffset() const;
+            
+            /*!
+             * Sets the else-offset of this ODD node.
+             *
+             * @param newOffset The new else-offset of this ODD node.
+             */
+            void setElseOffset(uint_fast64_t newOffset);
+            
+            /*!
+             * Retrieves the then-offset of this ODD node.
+             *
+             * @return The then-offset of this ODD node.
+             */
+            uint_fast64_t getThenOffset() const;
+            
+            /*!
+             * Sets the then-offset of this ODD node.
+             *
+             * @param newOffset The new then-offset of this ODD node.
+             */
+            void setThenOffset(uint_fast64_t newOffset);
+            
+            /*!
+             * Retrieves the total offset, i.e., the sum of the then- and else-offset.
+             *
+             * @return The total offset of this ODD.
+             */
+            uint_fast64_t getTotalOffset() const;
+            
+        private:
+            /*!
+             * Constructs an offset-labeled DD with the given topmost DD node, else- and then-successor.
+             *
+             * @param dd The DD associated with this ODD node.
+             * @param elseNode The else-successor of thie ODD node.
+             * @param elseOffset The offset of the else-successor.
+             * @param thenNode The then-successor of thie ODD node.
+             * @param thenOffset The offset of the then-successor.
+             */
+            Odd(ADD dd, std::shared_ptr<Odd<DdType::CUDD>>&& elseNode, uint_fast64_t elseOffset, std::shared_ptr<Odd<DdType::CUDD>>&& thenNode, uint_fast64_t thenOffset);
+            
+            /*!
+             * Recursively builds the ODD.
+             *
+             * @param dd The DD for which to build the ODD.
+             * @param manager The manager responsible for the DD.
+             * @param currentLevel The currently considered level in the DD.
+             * @param maxLevel The number of levels that need to be considered.
+             * @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
+             * @param uniqueTableForLevels A vector of unique tables, one for each level to be considered, that keeps
+             * ODD nodes for the same DD and level unique.
+             * @return A pointer to the constructed ODD for the given arguments.
+             */
+            static std::shared_ptr<Odd<DdType::CUDD>> buildOddRec(DdNode* dd, Cudd const& manager, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<std::map<DdNode*, std::shared_ptr<Odd<DdType::CUDD>>>>& uniqueTableForLevels);
+            
+            // The DD associated with this ODD node.
+            ADD dd;
+            
+            // The then- and else-nodes.
+            std::shared_ptr<Odd<DdType::CUDD>> elseNode;
+            std::shared_ptr<Odd<DdType::CUDD>> thenNode;
+            
+            // The offsets that need to be added if the then- or else-successor is taken, respectively.
+            uint_fast64_t elseOffset;
+            uint_fast64_t thenOffset;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_DD_CUDDODD_H_ */
\ No newline at end of file
diff --git a/src/storage/dd/Odd.h b/src/storage/dd/Odd.h
new file mode 100644
index 000000000..6a7231300
--- /dev/null
+++ b/src/storage/dd/Odd.h
@@ -0,0 +1,13 @@
+#ifndef STORM_STORAGE_DD_ODD_H_
+#define STORM_STORAGE_DD_ODD_H_
+
+#include "src/storage/dd/DdType.h"
+
+namespace storm {
+    namespace dd {
+        // Declare Odd class so we can then specialize it for the different DD types.
+        template<DdType Type> class Odd;
+    }
+}
+
+#endif /* STORM_STORAGE_DD_ODD_H_ */
\ No newline at end of file
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 391f8c96d..7f8a3f299 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -3,6 +3,7 @@
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/storage/dd/CuddDdManager.h"
 #include "src/storage/dd/CuddDd.h"
+#include "src/storage/dd/CuddOdd.h"
 #include "src/storage/dd/DdMetaVariable.h"
 
 TEST(CuddDdManager, Constants) {
@@ -375,4 +376,20 @@ TEST(CuddDd, ToExpressionTest) {
         // same value as the current value obtained from the DD.
         EXPECT_FALSE(mintermExpression.evaluateAsBool(&valuation));
     }
+}
+
+TEST(CuddDd, OddTest) {
+    std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
+    manager->addMetaVariable("x", 1, 9);
+    
+    storm::dd::Dd<storm::dd::DdType::CUDD> dd = manager->getIdentity("x");
+    storm::dd::Odd<storm::dd::DdType::CUDD> odd;
+    ASSERT_NO_THROW(odd = storm::dd::Odd<storm::dd::DdType::CUDD>(dd));
+    EXPECT_EQ(9, odd.getTotalOffset());
+    std::vector<double> ddAsVector;
+    ASSERT_NO_THROW(ddAsVector = dd.toDoubleVector());
+    EXPECT_EQ(9, ddAsVector.size());
+    for (uint_fast64_t i = 0; i < ddAsVector.size(); ++i) {
+        EXPECT_TRUE(i+1 == ddAsVector[i]);
+    }
 }
\ No newline at end of file

From f12ff82bafe522cad6b984c60624ace50fd65a0a Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 15 Jun 2014 19:27:39 +0200
Subject: [PATCH 142/147] Added getNodeCount for ODD and fixed a bug concerning
 boolean meta variables.

Former-commit-id: 79eb69226bb4dd39dfbdeb9f5af32440c2b5e4f7
---
 src/storage/dd/CuddDdMetaVariable.cpp  |  2 +-
 src/storage/dd/CuddOdd.cpp             | 14 ++++++++++++++
 src/storage/dd/CuddOdd.h               |  8 ++++++++
 test/functional/storage/CuddDdTest.cpp |  2 ++
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/storage/dd/CuddDdMetaVariable.cpp b/src/storage/dd/CuddDdMetaVariable.cpp
index 303cb192c..13667bd99 100644
--- a/src/storage/dd/CuddDdMetaVariable.cpp
+++ b/src/storage/dd/CuddDdMetaVariable.cpp
@@ -10,7 +10,7 @@ namespace storm {
             }
         }
         
-        DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Bool), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
+        DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Bool), low(0), high(1), ddVariables(ddVariables), cube(manager->getOne()), manager(manager) {
             // Create the cube of all variables of this meta variable.
             for (auto const& ddVariable : this->ddVariables) {
                 this->cube *= ddVariable;
diff --git a/src/storage/dd/CuddOdd.cpp b/src/storage/dd/CuddOdd.cpp
index 3f97dc861..dc84d9fd7 100644
--- a/src/storage/dd/CuddOdd.cpp
+++ b/src/storage/dd/CuddOdd.cpp
@@ -59,6 +59,20 @@ namespace storm {
             return this->elseOffset + this->thenOffset;
         }
         
+        uint_fast64_t Odd<DdType::CUDD>::getNodeCount() const {
+            // If the ODD contains a constant (and thus has no children), the size is 1.
+            if (this->elseNode == nullptr && this->thenNode == nullptr) {
+                return 1;
+            }
+            
+            // If the two successors are actually the same, we need to count the subnodes only once.
+            if (this->elseNode == this->thenNode) {
+                return this->elseNode->getNodeCount();
+            } else {
+                return this->elseNode->getNodeCount() + this->thenNode->getNodeCount();
+            }
+        }
+        
         std::shared_ptr<Odd<DdType::CUDD>> Odd<DdType::CUDD>::buildOddRec(DdNode* dd, Cudd const& manager, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<std::map<DdNode*, std::shared_ptr<Odd<DdType::CUDD>>>>& uniqueTableForLevels) {
             // Check whether the ODD for this node has already been computed (for this level) and if so, return this instead.
             auto const& iterator = uniqueTableForLevels[currentLevel].find(dd);
diff --git a/src/storage/dd/CuddOdd.h b/src/storage/dd/CuddOdd.h
index 2927bfde6..1d36613f0 100644
--- a/src/storage/dd/CuddOdd.h
+++ b/src/storage/dd/CuddOdd.h
@@ -80,6 +80,14 @@ namespace storm {
              */
             uint_fast64_t getTotalOffset() const;
             
+            /*!
+             * Retrieves the size of the ODD. Note: the size is computed by a traversal, so this may be costlier than
+             * expected.
+             *
+             * @return The size (in nodes) of this ODD.
+             */
+            uint_fast64_t getNodeCount() const;
+            
         private:
             /*!
              * Constructs an offset-labeled DD with the given topmost DD node, else- and then-successor.
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 7f8a3f299..5a6376e9f 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -386,6 +386,8 @@ TEST(CuddDd, OddTest) {
     storm::dd::Odd<storm::dd::DdType::CUDD> odd;
     ASSERT_NO_THROW(odd = storm::dd::Odd<storm::dd::DdType::CUDD>(dd));
     EXPECT_EQ(9, odd.getTotalOffset());
+    EXPECT_EQ(12, odd.getNodeCount());
+
     std::vector<double> ddAsVector;
     ASSERT_NO_THROW(ddAsVector = dd.toDoubleVector());
     EXPECT_EQ(9, ddAsVector.size());

From 236e7fa2908b29aeae48f30999f387314792e2ef Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 15 Jun 2014 22:45:49 +0200
Subject: [PATCH 143/147] Another step towards generating explicit data
 structures from DDs using ODDs.

Former-commit-id: 5b7e3e8680d385c60fb68c1024e960171688272b
---
 src/storage/dd/CuddDd.cpp              | 174 ++++++++++++++++++-------
 src/storage/dd/CuddDd.h                |  40 ++++--
 test/functional/storage/CuddDdTest.cpp |  33 +++--
 3 files changed, 181 insertions(+), 66 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index a7d9df2d1..3de67e8d0 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -119,138 +119,141 @@ namespace storm {
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::equals(Dd<DdType::CUDD> const& other) const {
-            Dd<DdType::CUDD> result(*this);
-            result.cuddAdd = result.cuddAdd.Equals(other.getCuddAdd());
-            return result;
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Equals(other.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::notEquals(Dd<DdType::CUDD> const& other) const {
-            Dd<DdType::CUDD> result(*this);
-            result.cuddAdd = result.cuddAdd.NotEquals(other.getCuddAdd());
-            return result;
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().NotEquals(other.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::less(Dd<DdType::CUDD> const& other) const {
-            Dd<DdType::CUDD> result(*this);
-            result.cuddAdd = result.cuddAdd.LessThan(other.getCuddAdd());
-            return result;
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().LessThan(other.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::lessOrEqual(Dd<DdType::CUDD> const& other) const {
-            Dd<DdType::CUDD> result(*this);
-            result.cuddAdd = result.cuddAdd.LessThanOrEqual(other.getCuddAdd());
-            return result;
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().LessThanOrEqual(other.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::greater(Dd<DdType::CUDD> const& other) const {
-            Dd<DdType::CUDD> result(*this);
-            result.cuddAdd = result.cuddAdd.GreaterThan(other.getCuddAdd());
-            return result;
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().GreaterThan(other.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::greaterOrEqual(Dd<DdType::CUDD> const& other) const {
-            Dd<DdType::CUDD> result(*this);
-            result.cuddAdd = result.cuddAdd.GreaterThanOrEqual(other.getCuddAdd());
-            return result;
+            std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
+            metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().GreaterThanOrEqual(other.getCuddAdd()), metaVariableNames);
         }
         
         Dd<DdType::CUDD> Dd<DdType::CUDD>::minimum(Dd<DdType::CUDD> const& other) const {
             std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
             metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
-            
             return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Minimum(other.getCuddAdd()), metaVariableNames);
         }
 
         Dd<DdType::CUDD> Dd<DdType::CUDD>::maximum(Dd<DdType::CUDD> const& other) const {
             std::set<std::string> metaVariableNames(this->getContainedMetaVariableNames());
             metaVariableNames.insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
-            
             return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddAdd().Maximum(other.getCuddAdd()), metaVariableNames);
         }
 
-        void Dd<DdType::CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) const {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
+            std::set<std::string> newMetaVariables = this->getContainedMetaVariableNames();
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
                 if (!this->containsMetaVariable(metaVariableName)) {
                     throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
                 }
-                this->getContainedMetaVariableNames().erase(metaVariableName);
+                newMetaVariables.erase(metaVariableName);
                 
                 DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd = this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.OrAbstract(cubeDd.getCuddAdd()), newMetaVariables);
         }
         
-        void Dd<DdType::CUDD>::universalAbstract(std::set<std::string> const& metaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::universalAbstract(std::set<std::string> const& metaVariableNames) const {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
+            std::set<std::string> newMetaVariables = this->getContainedMetaVariableNames();
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
                 if (!this->containsMetaVariable(metaVariableName)) {
                     throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
                 }
-                this->getContainedMetaVariableNames().erase(metaVariableName);
+                newMetaVariables.erase(metaVariableName);
                 
                 DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd = this->cuddAdd.UnivAbstract(cubeDd.getCuddAdd());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.UnivAbstract(cubeDd.getCuddAdd()), newMetaVariables);
         }
         
-        void Dd<DdType::CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) const {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
+            std::set<std::string> newMetaVariables = this->getContainedMetaVariableNames();
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
                 if (!this->containsMetaVariable(metaVariableName)) {
                     throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
                 }
-                this->getContainedMetaVariableNames().erase(metaVariableName);
+                newMetaVariables.erase(metaVariableName);
                 
                 DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd = this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd()), newMetaVariables);
         }
         
-        void Dd<DdType::CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) const {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
+            std::set<std::string> newMetaVariables = this->getContainedMetaVariableNames();
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
                 if (!this->containsMetaVariable(metaVariableName)) {
                     throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
                 }
-                this->getContainedMetaVariableNames().erase(metaVariableName);
+                newMetaVariables.erase(metaVariableName);
                 
                 DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd = this->cuddAdd.MinAbstract(cubeDd.getCuddAdd());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.MinAbstract(cubeDd.getCuddAdd()), newMetaVariables);
         }
         
-        void Dd<DdType::CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
+        Dd<DdType::CUDD> Dd<DdType::CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) const {
             Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
             
+            std::set<std::string> newMetaVariables = this->getContainedMetaVariableNames();
             for (auto const& metaVariableName : metaVariableNames) {
                 // First check whether the DD contains the meta variable and erase it, if this is the case.
                 if (!this->containsMetaVariable(metaVariableName)) {
                     throw storm::exceptions::InvalidArgumentException() << "Cannot abstract from meta variable that is not present in the DD.";
                 }
-                this->getContainedMetaVariableNames().erase(metaVariableName);
+                newMetaVariables.erase(metaVariableName);
                 
                 DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
                 cubeDd *= metaVariable.getCube();
             }
             
-            this->cuddAdd = this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd());
+            return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd()), newMetaVariables);
         }
         
         bool Dd<DdType::CUDD>::equalModuloPrecision(Dd<DdType::CUDD> const& other, double precision, bool relative) const {
@@ -410,7 +413,7 @@ namespace storm {
             }
             
             Dd<DdType::CUDD> value = *this * valueEncoding;
-            value.sumAbstract(this->getContainedMetaVariableNames());
+            value = value.sumAbstract(this->getContainedMetaVariableNames());
             return static_cast<double>(Cudd_V(value.getCuddAdd().getNode()));
         }
         
@@ -430,18 +433,19 @@ namespace storm {
             return static_cast<uint_fast64_t>(this->getCuddAdd().NodeReadIndex());
         }
         
-        std::vector<double> Dd<DdType::CUDD>::toDoubleVector() const {
-            return this->toDoubleVector(Odd<DdType::CUDD>(*this));
+        std::vector<double> Dd<DdType::CUDD>::toVector() const {
+            return this->toVector(Odd<DdType::CUDD>(*this));
         }
         
-        std::vector<double> Dd<DdType::CUDD>::toDoubleVector(Odd<DdType::CUDD> const& odd) const {
+        std::vector<double> Dd<DdType::CUDD>::toVector(Odd<DdType::CUDD> const& odd) const {
             std::vector<double> result(odd.getTotalOffset());
             std::vector<uint_fast64_t> ddVariableIndices = this->getSortedVariableIndices();
-            toDoubleVectorRec(this->getCuddAdd().getNode(), result, odd, 0, ddVariableIndices.size(), 0, ddVariableIndices);
+            toVectorRec(this->getCuddAdd().getNode(), result, odd, 0, ddVariableIndices.size(), 0, ddVariableIndices);
             return result;
         }
         
-        void Dd<DdType::CUDD>::toDoubleVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const {
+        void Dd<DdType::CUDD>::toVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const {
+            // For the empty DD, we do not need to add any entries.
             if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
                 return;
             }
@@ -452,12 +456,92 @@ namespace storm {
             } else if (ddVariableIndices[currentLevel] < dd->index) {
                 // If we skipped a level, we need to enumerate the explicit entries for the case in which the bit is set
                 // and for the one in which it is not set.
-                toDoubleVectorRec(dd, result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
-                toDoubleVectorRec(dd, result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
+                toVectorRec(dd, result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
+                toVectorRec(dd, result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
             } else {
                 // Otherwise, we simply recursively call the function for both (different) cases.
-                toDoubleVectorRec(Cudd_E(dd), result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
-                toDoubleVectorRec(Cudd_T(dd), result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
+                toVectorRec(Cudd_E(dd), result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
+                toVectorRec(Cudd_T(dd), result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
+            }
+        }
+        
+        storm::storage::SparseMatrix<double> Dd<DdType::CUDD>::toMatrix() const {
+            std::set<std::string> rowVariables;
+            std::set<std::string> columnVariables;
+            std::vector<uint_fast64_t> ddRowVariableIndices;
+            std::vector<uint_fast64_t> ddColumnVariableIndices;
+
+            for (auto const& variableName : this->getContainedMetaVariableNames()) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
+                if (variableName.size() > 0 && variableName.back() == '\'') {
+                    columnVariables.insert(variableName);
+                    for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                        ddColumnVariableIndices.push_back(ddVariable.getIndex());
+                    }
+                } else {
+                    rowVariables.insert(variableName);
+                    for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                        ddRowVariableIndices.push_back(ddVariable.getIndex());
+                    }
+                }
+            }
+            
+            Odd<DdType::CUDD> columnOdd(this->existsAbstract(rowVariables));
+            Odd<DdType::CUDD> rowOdd(this->existsAbstract(columnVariables));
+            
+            storm::storage::SparseMatrixBuilder<double> builder;
+            toMatrixRec(this->getCuddAdd().getNode(), builder, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices);
+            return builder.build();
+        }
+        
+        void Dd<DdType::CUDD>::toMatrixRec(DdNode const* dd, storm::storage::SparseMatrixBuilder<double>& builder, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices) const {
+            // FIXME: this method currently assumes a strict interleaved order, which does not seem necessary.
+            
+            // For the empty DD, we do not need to add any entries.
+            if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
+                return;
+            }
+
+            // If we are at the maximal level, the value to be set is stored as a constant in the DD.
+            if (currentRowLevel + currentColumnLevel == maxLevel) {
+                builder.addNextValue(currentRowOffset, currentColumnOffset, Cudd_V(dd));
+            } else {
+                DdNode const* elseElse;
+                DdNode const* elseThen;
+                DdNode const* thenElse;
+                DdNode const* thenThen;
+                
+                if (ddColumnVariableIndices[currentColumnLevel] < dd->index) {
+                    elseElse = elseThen = thenElse = thenThen = dd;
+                } else if (ddRowVariableIndices[currentColumnLevel] < dd->index) {
+                    elseElse = thenElse = Cudd_E(dd);
+                    elseThen = thenThen = Cudd_T(dd);
+                } else {
+                    DdNode const* elseNode = Cudd_E(dd);
+                    if (ddColumnVariableIndices[currentColumnLevel] < elseNode->index) {
+                        elseElse = elseThen = elseNode;
+                    } else {
+                        elseElse = Cudd_E(elseNode);
+                        elseThen = Cudd_T(elseNode);
+                    }
+
+                    DdNode const* thenNode = Cudd_T(dd);
+                    if (ddColumnVariableIndices[currentColumnLevel] < thenNode->index) {
+                        thenElse = thenThen = thenNode;
+                    } else {
+                        thenElse = Cudd_E(thenNode);
+                        thenThen = Cudd_T(thenNode);
+                    }
+                }
+                
+                // Visit else-else.
+                toMatrixRec(elseElse, builder, rowOdd.getElseSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices);
+                // Visit else-then.
+                toMatrixRec(elseThen, builder, rowOdd.getElseSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices);
+                // Visit then-else.
+                toMatrixRec(thenElse, builder, rowOdd.getThenSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices);
+                // Visit then-then.
+                toMatrixRec(thenThen, builder, rowOdd.getThenSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices);
             }
         }
         
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index a7951cfb3..6a25b8c78 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -8,6 +8,7 @@
 
 #include "src/storage/dd/Dd.h"
 #include "src/storage/dd/CuddDdForwardIterator.h"
+#include "src/storage/SparseMatrix.h"
 #include "src/storage/expressions/Expression.h"
 #include "src/utility/OsDetection.h"
 
@@ -234,35 +235,35 @@ namespace storm {
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void existsAbstract(std::set<std::string> const& metaVariableNames);
+            Dd<DdType::CUDD> existsAbstract(std::set<std::string> const& metaVariableNames) const;
             
             /*!
              * Universally abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void universalAbstract(std::set<std::string> const& metaVariableNames);
+            Dd<DdType::CUDD> universalAbstract(std::set<std::string> const& metaVariableNames) const;
             
             /*!
              * Sum-abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void sumAbstract(std::set<std::string> const& metaVariableNames);
+            Dd<DdType::CUDD> sumAbstract(std::set<std::string> const& metaVariableNames) const;
             
             /*!
              * Min-abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void minAbstract(std::set<std::string> const& metaVariableNames);
+            Dd<DdType::CUDD> minAbstract(std::set<std::string> const& metaVariableNames) const;
             
             /*!
              * Max-abstracts from the given meta variables.
              *
              * @param metaVariableNames The names of all meta variables from which to abstract.
              */
-            void maxAbstract(std::set<std::string> const& metaVariableNames);
+            Dd<DdType::CUDD> maxAbstract(std::set<std::string> const& metaVariableNames) const;
             
             /*!
              * Checks whether the current and the given DD represent the same function modulo some given precision.
@@ -461,7 +462,13 @@ namespace storm {
              *
              * @return The double vector that is represented by this DD.
              */
-            std::vector<double> toDoubleVector() const;
+            std::vector<double> toVector() const;
+            
+            /*!
+             * Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
+             * row, whereas all primed variables are assumed to encode the column.
+             */
+            storm::storage::SparseMatrix<double> toMatrix() const;
             
             /*!
              * Converts the DD to a double vector using the given ODD (that needs to be constructed for the DD).
@@ -469,7 +476,7 @@ namespace storm {
              * @param odd The ODD for the DD.
              * @return The double vector that is represented by this DD.
              */
-            std::vector<double> toDoubleVector(Odd<DdType::CUDD> const& odd) const;
+            std::vector<double> toVector(Odd<DdType::CUDD> const& odd) const;
             
             /*!
              * Retrieves whether the given meta variable is contained in the DD.
@@ -623,7 +630,24 @@ namespace storm {
              * @param currentOffset The current offset.
              * @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
              */
-            void toDoubleVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const;
+            void toVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const;
+            
+            /*!
+             * Helper function to convert the DD into a (sparse) matrix.
+             *
+             * @param dd The DD to convert.
+             * @param builder A matrix builder that can be used to insert the nonzero entries.
+             * @param rowOdd The ODD used for the row translation.
+             * @param columnOdd The ODD used for the column translation.
+             * @param currentRowLevel The currently considered row level in the DD.
+             * @param currentColumnLevel The currently considered row level in the DD.
+             * @param maxLevel The number of levels that need to be considered.
+             * @param currentRowOffset The current row offset.
+             * @param currentColumnOffset The current row offset.
+             * @param ddRowVariableIndices The (sorted) indices of all DD row variables that need to be considered.
+             * @param ddColumnVariableIndices The (sorted) indices of all DD row variables that need to be considered.
+             */
+            void toMatrixRec(DdNode const* dd, storm::storage::SparseMatrixBuilder<double>& builder, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices) const;
             
             /*!
              * Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 5a6376e9f..0c75253b5 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -163,12 +163,12 @@ TEST(CuddDd, OperatorTest) {
     
     dd4 = dd3.minimum(dd1);
     dd4 *= manager->getEncoding("x", 2);
-    dd4.sumAbstract({"x"});
+    dd4 = dd4.sumAbstract({"x"});
     EXPECT_EQ(2, dd4.getValue());
 
     dd4 = dd3.maximum(dd1);
     dd4 *= manager->getEncoding("x", 2);
-    dd4.sumAbstract({"x"});
+    dd4 = dd4.sumAbstract({"x"});
     EXPECT_EQ(5, dd4.getValue());
 
     dd1 = manager->getConstant(0.01);
@@ -188,36 +188,36 @@ TEST(CuddDd, AbstractionTest) {
     dd2 = manager->getConstant(5);
     dd3 = dd1.equals(dd2);
     EXPECT_EQ(1, dd3.getNonZeroCount());
-    ASSERT_THROW(dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(dd3.existsAbstract({"x"}));
+    ASSERT_THROW(dd3 = dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3 = dd3.existsAbstract({"x"}));
     EXPECT_EQ(1, dd3.getNonZeroCount());
     EXPECT_EQ(1, dd3.getMax());
 
     dd3 = dd1.equals(dd2);
     dd3 *= manager->getConstant(3);
     EXPECT_EQ(1, dd3.getNonZeroCount());
-    ASSERT_THROW(dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(dd3.existsAbstract({"x"}));
+    ASSERT_THROW(dd3 = dd3.existsAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3 = dd3.existsAbstract({"x"}));
     EXPECT_TRUE(dd3 == manager->getZero());
 
     dd3 = dd1.equals(dd2);
     dd3 *= manager->getConstant(3);
-    ASSERT_THROW(dd3.sumAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(dd3.sumAbstract({"x"}));
+    ASSERT_THROW(dd3 = dd3.sumAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3 = dd3.sumAbstract({"x"}));
     EXPECT_EQ(1, dd3.getNonZeroCount());
     EXPECT_EQ(3, dd3.getMax());
 
     dd3 = dd1.equals(dd2);
     dd3 *= manager->getConstant(3);
-    ASSERT_THROW(dd3.minAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(dd3.minAbstract({"x"}));
+    ASSERT_THROW(dd3 = dd3.minAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3 = dd3.minAbstract({"x"}));
     EXPECT_EQ(0, dd3.getNonZeroCount());
     EXPECT_EQ(0, dd3.getMax());
 
     dd3 = dd1.equals(dd2);
     dd3 *= manager->getConstant(3);
-    ASSERT_THROW(dd3.maxAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
-    ASSERT_NO_THROW(dd3.maxAbstract({"x"}));
+    ASSERT_THROW(dd3 = dd3.maxAbstract({"x'"}), storm::exceptions::InvalidArgumentException);
+    ASSERT_NO_THROW(dd3 = dd3.maxAbstract({"x"}));
     EXPECT_EQ(1, dd3.getNonZeroCount());
     EXPECT_EQ(3, dd3.getMax());
 }
@@ -389,9 +389,16 @@ TEST(CuddDd, OddTest) {
     EXPECT_EQ(12, odd.getNodeCount());
 
     std::vector<double> ddAsVector;
-    ASSERT_NO_THROW(ddAsVector = dd.toDoubleVector());
+    ASSERT_NO_THROW(ddAsVector = dd.toVector());
     EXPECT_EQ(9, ddAsVector.size());
     for (uint_fast64_t i = 0; i < ddAsVector.size(); ++i) {
         EXPECT_TRUE(i+1 == ddAsVector[i]);
     }
+    
+    dd = manager->getIdentity("x").equals(manager->getIdentity("x'")) * manager->getRange("x");
+    storm::storage::SparseMatrix<double> matrix;
+    ASSERT_NO_THROW(matrix = dd.toMatrix());
+    EXPECT_EQ(9, matrix.getRowCount());
+    EXPECT_EQ(9, matrix.getColumnCount());
+    EXPECT_EQ(9, matrix.getNonzeroEntryCount());
 }
\ No newline at end of file

From 084bb14acd9984872f331c482965d7f2a9b39d0b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 16 Jun 2014 09:23:43 +0200
Subject: [PATCH 144/147] Bugfix for expression parser.

Former-commit-id: 2b03856c86bf8650145f472710be0d860221213c
---
 src/parser/ExpressionParser.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp
index bb143a2c0..6459d7a9d 100644
--- a/src/parser/ExpressionParser.cpp
+++ b/src/parser/ExpressionParser.cpp
@@ -300,9 +300,9 @@ namespace storm {
         
         storm::expressions::Expression ExpressionParser::createTrueExpression() const {
             if (this->createExpressions) {
-                return storm::expressions::Expression::createFalse();
-            } else {
                 return storm::expressions::Expression::createTrue();
+            } else {
+                return storm::expressions::Expression::createFalse();
             }
         }
         

From 8587f68eb17e3f74c7bd77fc83c455b1b8a9e735 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 17 Jun 2014 23:33:55 +0200
Subject: [PATCH 145/147] Fixed toMatrix conversion using ODDs. The next step
 is to generate non-deterministic matrices, i.e., matrices with row groups.

Former-commit-id: e4a9c5f0ed3f2eac5712f7a8e8d825641ca17c35
---
 src/storage/dd/CuddDd.cpp              | 55 +++++++++++++++++++++-----
 src/storage/dd/CuddDd.h                | 13 +++++-
 test/functional/storage/CuddDdTest.cpp |  3 +-
 3 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 3de67e8d0..4eb5eff5a 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -489,12 +489,46 @@ namespace storm {
             Odd<DdType::CUDD> columnOdd(this->existsAbstract(rowVariables));
             Odd<DdType::CUDD> rowOdd(this->existsAbstract(columnVariables));
             
-            storm::storage::SparseMatrixBuilder<double> builder;
-            toMatrixRec(this->getCuddAdd().getNode(), builder, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices);
-            return builder.build();
+            // Prepare the vectors that represent the matrix.
+            std::vector<uint_fast64_t> rowIndications(rowOdd.getTotalOffset() + 1);
+            std::vector<storm::storage::MatrixEntry<double>> columnsAndValues(this->getNonZeroCount());
+            
+            // Use the toMatrixRec function to compute the number of elements in each row. Using the flag, we prevent
+            // it from actually generating the entries in the entry vector.
+            toMatrixRec(this->getCuddAdd().getNode(), rowIndications, columnsAndValues, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, false);
+
+            // Now that we computed the number of entries in each row, compute the corresponding offsets in the entry vector.
+            uint_fast64_t tmp = 0;
+            uint_fast64_t tmp2 = 0;
+            for (uint_fast64_t i = 1; i < rowIndications.size(); ++i) {
+                tmp2 = rowIndications[i];
+                rowIndications[i] = rowIndications[i - 1] + tmp;
+                std::swap(tmp, tmp2);
+            }
+            rowIndications[0] = 0;
+            
+            // Now actually fill the entry vector.
+            toMatrixRec(this->getCuddAdd().getNode(), rowIndications, columnsAndValues, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, true);
+            
+            // Since the last call to toMatrixRec modified the rowIndications, we need to restore the correct values.
+            for (uint_fast64_t i = rowIndications.size() - 1; i > 0; --i) {
+                rowIndications[i] = rowIndications[i - 1];
+            }
+            rowIndications[0] = 0;
+            
+            // Create a trivial row grouping.
+            std::vector<uint_fast64_t> trivialRowGroupIndices(rowIndications.size());
+            uint_fast64_t i = 0;
+            for (auto& entry : trivialRowGroupIndices) {
+                entry = i;
+                ++i;
+            }
+            
+            // Construct matrix and return result.
+            return storm::storage::SparseMatrix<double>(columnOdd.getTotalOffset(), std::move(rowIndications), std::move(columnsAndValues), std::move(trivialRowGroupIndices));
         }
         
-        void Dd<DdType::CUDD>::toMatrixRec(DdNode const* dd, storm::storage::SparseMatrixBuilder<double>& builder, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices) const {
+        void Dd<DdType::CUDD>::toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<double>>& columnsAndValues, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues) const {
             // FIXME: this method currently assumes a strict interleaved order, which does not seem necessary.
             
             // For the empty DD, we do not need to add any entries.
@@ -504,7 +538,10 @@ namespace storm {
 
             // If we are at the maximal level, the value to be set is stored as a constant in the DD.
             if (currentRowLevel + currentColumnLevel == maxLevel) {
-                builder.addNextValue(currentRowOffset, currentColumnOffset, Cudd_V(dd));
+                if (generateValues) {
+                    columnsAndValues[rowIndications[currentRowOffset]] = storm::storage::MatrixEntry<double>(currentColumnOffset, Cudd_V(dd));
+                }
+                ++rowIndications[currentRowOffset];
             } else {
                 DdNode const* elseElse;
                 DdNode const* elseThen;
@@ -535,13 +572,13 @@ namespace storm {
                 }
                 
                 // Visit else-else.
-                toMatrixRec(elseElse, builder, rowOdd.getElseSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices);
+                toMatrixRec(elseElse, rowIndications, columnsAndValues, rowOdd.getElseSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
                 // Visit else-then.
-                toMatrixRec(elseThen, builder, rowOdd.getElseSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices);
+                toMatrixRec(elseThen, rowIndications, columnsAndValues, rowOdd.getElseSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
                 // Visit then-else.
-                toMatrixRec(thenElse, builder, rowOdd.getThenSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices);
+                toMatrixRec(thenElse, rowIndications, columnsAndValues, rowOdd.getThenSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
                 // Visit then-then.
-                toMatrixRec(thenThen, builder, rowOdd.getThenSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices);
+                toMatrixRec(thenThen, rowIndications, columnsAndValues, rowOdd.getThenSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
             }
         }
         
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 6a25b8c78..045f547a0 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -636,7 +636,13 @@ namespace storm {
              * Helper function to convert the DD into a (sparse) matrix.
              *
              * @param dd The DD to convert.
-             * @param builder A matrix builder that can be used to insert the nonzero entries.
+             * @param rowIndications A vector indicating at which position in the columnsAndValues vector the entries
+             * of row i start. Note: this vector is modified in the computation. More concretely, each entry i in the
+             * vector will be increased by the number of entries in the row. This can be used to count the number
+             * of entries in each row. If the values are not to be modified, a copy needs to be provided or the entries
+             * need to be restored afterwards.
+             * @param columnsAndValues The vector that will hold the columns and values of non-zero entries upon successful
+             * completion.
              * @param rowOdd The ODD used for the row translation.
              * @param columnOdd The ODD used for the column translation.
              * @param currentRowLevel The currently considered row level in the DD.
@@ -646,8 +652,11 @@ namespace storm {
              * @param currentColumnOffset The current row offset.
              * @param ddRowVariableIndices The (sorted) indices of all DD row variables that need to be considered.
              * @param ddColumnVariableIndices The (sorted) indices of all DD row variables that need to be considered.
+             * @param generateValues If set to true, the vector columnsAndValues is filled with the actual entries, which
+             * only works if the offsets given in rowIndications are already correct. If they need to be computed first,
+             * this flag needs to be false.
              */
-            void toMatrixRec(DdNode const* dd, storm::storage::SparseMatrixBuilder<double>& builder, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices) const;
+            void toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<double>>& columnsAndValues, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues = true) const;
             
             /*!
              * Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 0c75253b5..98a528b3d 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -396,9 +396,10 @@ TEST(CuddDd, OddTest) {
     }
     
     dd = manager->getIdentity("x").equals(manager->getIdentity("x'")) * manager->getRange("x");
+    dd += manager->getEncoding("x", 1) * manager->getRange("x'") + manager->getEncoding("x'", 1) * manager->getRange("x");
     storm::storage::SparseMatrix<double> matrix;
     ASSERT_NO_THROW(matrix = dd.toMatrix());
     EXPECT_EQ(9, matrix.getRowCount());
     EXPECT_EQ(9, matrix.getColumnCount());
-    EXPECT_EQ(9, matrix.getNonzeroEntryCount());
+    EXPECT_EQ(25, matrix.getNonzeroEntryCount());
 }
\ No newline at end of file

From caf96c04e064b96962be109e80081a1296d517a8 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 19 Jun 2014 18:53:43 +0200
Subject: [PATCH 146/147] Extended DD interface by methods to generate explicit
 row-grouped matrices from DDs.

Former-commit-id: 1945d7be6d2e86992df17fcf3270a98c4c8a25fa
---
 src/storage/dd/CuddDd.cpp              | 270 +++++++++++++++++++------
 src/storage/dd/CuddDd.h                |  97 +++++++--
 test/functional/storage/CuddDdTest.cpp |  22 +-
 3 files changed, 308 insertions(+), 81 deletions(-)

diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp
index 4eb5eff5a..57cda7018 100644
--- a/src/storage/dd/CuddDd.cpp
+++ b/src/storage/dd/CuddDd.cpp
@@ -4,6 +4,7 @@
 #include "src/storage/dd/CuddDd.h"
 #include "src/storage/dd/CuddOdd.h"
 #include "src/storage/dd/CuddDdManager.h"
+#include "src/utility/vector.h"
 
 #include "src/exceptions/InvalidArgumentException.h"
 
@@ -433,70 +434,85 @@ namespace storm {
             return static_cast<uint_fast64_t>(this->getCuddAdd().NodeReadIndex());
         }
         
-        std::vector<double> Dd<DdType::CUDD>::toVector() const {
-            return this->toVector(Odd<DdType::CUDD>(*this));
+        template<typename ValueType>
+        std::vector<ValueType> Dd<DdType::CUDD>::toVector() const {
+            return this->toVector<ValueType>(Odd<DdType::CUDD>(*this));
         }
         
-        std::vector<double> Dd<DdType::CUDD>::toVector(Odd<DdType::CUDD> const& odd) const {
-            std::vector<double> result(odd.getTotalOffset());
+        template<typename ValueType>
+        std::vector<ValueType> Dd<DdType::CUDD>::toVector(Odd<DdType::CUDD> const& rowOdd) const {
+            std::vector<ValueType> result(rowOdd.getTotalOffset());
             std::vector<uint_fast64_t> ddVariableIndices = this->getSortedVariableIndices();
-            toVectorRec(this->getCuddAdd().getNode(), result, odd, 0, ddVariableIndices.size(), 0, ddVariableIndices);
+            addToVectorRec(this->getCuddAdd().getNode(), 0, ddVariableIndices.size(), 0, rowOdd, ddVariableIndices, result);
             return result;
         }
         
-        void Dd<DdType::CUDD>::toVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const {
-            // For the empty DD, we do not need to add any entries.
-            if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
-                return;
-            }
-            
-            // If we are at the maximal level, the value to be set is stored as a constant in the DD.
-            if (currentLevel == maxLevel) {
-                result[currentOffset] = Cudd_V(dd);
-            } else if (ddVariableIndices[currentLevel] < dd->index) {
-                // If we skipped a level, we need to enumerate the explicit entries for the case in which the bit is set
-                // and for the one in which it is not set.
-                toVectorRec(dd, result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
-                toVectorRec(dd, result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
-            } else {
-                // Otherwise, we simply recursively call the function for both (different) cases.
-                toVectorRec(Cudd_E(dd), result, odd.getElseSuccessor(), currentLevel + 1, maxLevel, currentOffset, ddVariableIndices);
-                toVectorRec(Cudd_T(dd), result, odd.getThenSuccessor(), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), ddVariableIndices);
-            }
-        }
-        
         storm::storage::SparseMatrix<double> Dd<DdType::CUDD>::toMatrix() const {
             std::set<std::string> rowVariables;
             std::set<std::string> columnVariables;
-            std::vector<uint_fast64_t> ddRowVariableIndices;
-            std::vector<uint_fast64_t> ddColumnVariableIndices;
-
+            
             for (auto const& variableName : this->getContainedMetaVariableNames()) {
-                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
                 if (variableName.size() > 0 && variableName.back() == '\'') {
                     columnVariables.insert(variableName);
-                    for (auto const& ddVariable : metaVariable.getDdVariables()) {
-                        ddColumnVariableIndices.push_back(ddVariable.getIndex());
-                    }
                 } else {
                     rowVariables.insert(variableName);
-                    for (auto const& ddVariable : metaVariable.getDdVariables()) {
-                        ddRowVariableIndices.push_back(ddVariable.getIndex());
-                    }
+                }
+            }
+
+            return toMatrix(rowVariables, columnVariables, Odd<DdType::CUDD>(this->existsAbstract(rowVariables)), Odd<DdType::CUDD>(this->existsAbstract(columnVariables)));
+        }
+        
+        storm::storage::SparseMatrix<double> Dd<DdType::CUDD>::toMatrix(storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const {
+            std::set<std::string> rowMetaVariables;
+            std::set<std::string> columnMetaVariables;
+
+            for (auto const& variableName : this->getContainedMetaVariableNames()) {
+                if (variableName.size() > 0 && variableName.back() == '\'') {
+                    columnMetaVariables.insert(variableName);
+                } else {
+                    rowMetaVariables.insert(variableName);
                 }
             }
             
-            Odd<DdType::CUDD> columnOdd(this->existsAbstract(rowVariables));
-            Odd<DdType::CUDD> rowOdd(this->existsAbstract(columnVariables));
+            return toMatrix(rowMetaVariables, columnMetaVariables, rowOdd, columnOdd);
+        }
+        
+        storm::storage::SparseMatrix<double> Dd<DdType::CUDD>::toMatrix(std::set<std::string> const& rowMetaVariables, std::set<std::string> const& columnMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const {
+            std::vector<uint_fast64_t> ddRowVariableIndices;
+            std::vector<uint_fast64_t> ddColumnVariableIndices;
+            
+            for (auto const& variableName : rowMetaVariables) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
+                for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                    ddRowVariableIndices.push_back(ddVariable.getIndex());
+                }
+            }
+            for (auto const& variableName : columnMetaVariables) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
+                for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                    ddColumnVariableIndices.push_back(ddVariable.getIndex());
+                }
+            }
             
             // Prepare the vectors that represent the matrix.
             std::vector<uint_fast64_t> rowIndications(rowOdd.getTotalOffset() + 1);
             std::vector<storm::storage::MatrixEntry<double>> columnsAndValues(this->getNonZeroCount());
             
+            // Create a trivial row grouping.
+            std::vector<uint_fast64_t> trivialRowGroupIndices(rowIndications.size());
+            uint_fast64_t i = 0;
+            for (auto& entry : trivialRowGroupIndices) {
+                entry = i;
+                ++i;
+            }
+            
             // Use the toMatrixRec function to compute the number of elements in each row. Using the flag, we prevent
             // it from actually generating the entries in the entry vector.
-            toMatrixRec(this->getCuddAdd().getNode(), rowIndications, columnsAndValues, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, false);
-
+            toMatrixRec(this->getCuddAdd().getNode(), rowIndications, columnsAndValues, trivialRowGroupIndices, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, false);
+            
+            // TODO: counting might be faster by just summing over the primed variables and then using the ODD to convert
+            // the resulting (DD) vector to an explicit vector.
+            
             // Now that we computed the number of entries in each row, compute the corresponding offsets in the entry vector.
             uint_fast64_t tmp = 0;
             uint_fast64_t tmp2 = 0;
@@ -508,7 +524,7 @@ namespace storm {
             rowIndications[0] = 0;
             
             // Now actually fill the entry vector.
-            toMatrixRec(this->getCuddAdd().getNode(), rowIndications, columnsAndValues, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, true);
+            toMatrixRec(this->getCuddAdd().getNode(), rowIndications, columnsAndValues, trivialRowGroupIndices, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, true);
             
             // Since the last call to toMatrixRec modified the rowIndications, we need to restore the correct values.
             for (uint_fast64_t i = rowIndications.size() - 1; i > 0; --i) {
@@ -516,21 +532,113 @@ namespace storm {
             }
             rowIndications[0] = 0;
             
-            // Create a trivial row grouping.
-            std::vector<uint_fast64_t> trivialRowGroupIndices(rowIndications.size());
-            uint_fast64_t i = 0;
-            for (auto& entry : trivialRowGroupIndices) {
-                entry = i;
-                ++i;
-            }
-            
             // Construct matrix and return result.
             return storm::storage::SparseMatrix<double>(columnOdd.getTotalOffset(), std::move(rowIndications), std::move(columnsAndValues), std::move(trivialRowGroupIndices));
         }
         
-        void Dd<DdType::CUDD>::toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<double>>& columnsAndValues, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues) const {
-            // FIXME: this method currently assumes a strict interleaved order, which does not seem necessary.
+        storm::storage::SparseMatrix<double> Dd<DdType::CUDD>::toMatrix(std::set<std::string> const& rowMetaVariables, std::set<std::string> const& columnMetaVariables, std::set<std::string> const& groupMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const {
+            std::vector<uint_fast64_t> ddRowVariableIndices;
+            std::vector<uint_fast64_t> ddColumnVariableIndices;
+            std::vector<uint_fast64_t> ddGroupVariableIndices;
+            std::set<std::string> rowAndColumnMetaVariables;
+            
+            for (auto const& variableName : rowMetaVariables) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
+                for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                    ddRowVariableIndices.push_back(ddVariable.getIndex());
+                }
+                rowAndColumnMetaVariables.insert(variableName);
+            }
+            for (auto const& variableName : columnMetaVariables) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
+                for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                    ddColumnVariableIndices.push_back(ddVariable.getIndex());
+                }
+                rowAndColumnMetaVariables.insert(variableName);
+            }
+            for (auto const& variableName : groupMetaVariables) {
+                DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(variableName);
+                for (auto const& ddVariable : metaVariable.getDdVariables()) {
+                    ddGroupVariableIndices.push_back(ddVariable.getIndex());
+                }
+            }
+
+            // TODO: assert that the group variables are at the very top of the variable ordering?
+            
+            // Start by computing the offsets (in terms of rows) for each row group.
+            Dd<DdType::CUDD> stateToNumberOfChoices = this->notZero().existsAbstract(columnMetaVariables).sumAbstract(groupMetaVariables);
+            std::vector<uint_fast64_t> rowGroupIndices = stateToNumberOfChoices.toVector<uint_fast64_t>(rowOdd);
+            rowGroupIndices.resize(rowGroupIndices.size() + 1);
+            uint_fast64_t tmp = 0;
+            uint_fast64_t tmp2 = 0;
+            for (uint_fast64_t i = 1; i < rowGroupIndices.size(); ++i) {
+                tmp2 = rowGroupIndices[i];
+                rowGroupIndices[i] = rowGroupIndices[i - 1] + tmp;
+                std::swap(tmp, tmp2);
+            }
+            rowGroupIndices[0] = 0;
+            
+            // Next, we split the matrix into one for each group. This only works if the group variables are at the very
+            // top.
+            std::vector<Dd<DdType::CUDD>> groups;
+            splitGroupsRec(this->getCuddAdd().getNode(), groups, ddGroupVariableIndices, 0, ddGroupVariableIndices.size(), rowAndColumnMetaVariables);
+            
+            // Create the actual storage for the non-zero entries.
+            std::vector<storm::storage::MatrixEntry<double>> columnsAndValues(this->getNonZeroCount());
+            
+            // Now compute the indices at which the individual rows start.
+            std::vector<uint_fast64_t> rowIndications(rowGroupIndices.back() + 1);
+            std::vector<storm::dd::Dd<DdType::CUDD>> statesWithGroupEnabled(groups.size());
+            for (uint_fast64_t i = 0; i < groups.size(); ++i) {
+                auto const& dd = groups[i];
+                
+                toMatrixRec(dd.getCuddAdd().getNode(), rowIndications, columnsAndValues, rowGroupIndices, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, false);
+                
+                statesWithGroupEnabled[i] = dd.notZero().existsAbstract(columnMetaVariables);
+                addToVectorRec(statesWithGroupEnabled[i].getCuddAdd().getNode(), 0, ddRowVariableIndices.size(), 0, rowOdd, ddRowVariableIndices, rowGroupIndices);
+            }
+            
+            // Since we modified the rowGroupIndices, we need to restore the correct values.
+            for (uint_fast64_t i = rowGroupIndices.size() - 1; i > 0; --i) {
+                rowGroupIndices[i] = rowGroupIndices[i - 1];
+            }
+            rowGroupIndices[0] = 0;
+            
+            // Now that we computed the number of entries in each row, compute the corresponding offsets in the entry vector.
+            tmp = 0;
+            tmp2 = 0;
+            for (uint_fast64_t i = 1; i < rowIndications.size(); ++i) {
+                tmp2 = rowIndications[i];
+                rowIndications[i] = rowIndications[i - 1] + tmp;
+                std::swap(tmp, tmp2);
+            }
+            rowIndications[0] = 0;
             
+            // Now actually fill the entry vector.
+            for (uint_fast64_t i = 0; i < groups.size(); ++i) {
+                auto const& dd = groups[i];
+
+                toMatrixRec(dd.getCuddAdd().getNode(), rowIndications, columnsAndValues, rowGroupIndices, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0, ddRowVariableIndices, ddColumnVariableIndices, true);
+                
+                addToVectorRec(statesWithGroupEnabled[i].getCuddAdd().getNode(), 0, ddRowVariableIndices.size(), 0, rowOdd, ddRowVariableIndices, rowGroupIndices);
+            }
+            
+            // Since we modified the rowGroupIndices, we need to restore the correct values.
+            for (uint_fast64_t i = rowGroupIndices.size() - 1; i > 0; --i) {
+                rowGroupIndices[i] = rowGroupIndices[i - 1];
+            }
+            rowGroupIndices[0] = 0;
+            
+            // Since the last call to toMatrixRec modified the rowIndications, we need to restore the correct values.
+            for (uint_fast64_t i = rowIndications.size() - 1; i > 0; --i) {
+                rowIndications[i] = rowIndications[i - 1];
+            }
+            rowIndications[0] = 0;
+            
+            return storm::storage::SparseMatrix<double>(columnOdd.getTotalOffset(), std::move(rowIndications), std::move(columnsAndValues), std::move(rowGroupIndices));
+        }
+        
+        void Dd<DdType::CUDD>::toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<double>>& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupOffsets, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues) const {
             // For the empty DD, we do not need to add any entries.
             if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
                 return;
@@ -539,9 +647,9 @@ namespace storm {
             // If we are at the maximal level, the value to be set is stored as a constant in the DD.
             if (currentRowLevel + currentColumnLevel == maxLevel) {
                 if (generateValues) {
-                    columnsAndValues[rowIndications[currentRowOffset]] = storm::storage::MatrixEntry<double>(currentColumnOffset, Cudd_V(dd));
+                    columnsAndValues[rowIndications[rowGroupOffsets[currentRowOffset]]] = storm::storage::MatrixEntry<double>(currentColumnOffset, Cudd_V(dd));
                 }
-                ++rowIndications[currentRowOffset];
+                ++rowIndications[rowGroupOffsets[currentRowOffset]];
             } else {
                 DdNode const* elseElse;
                 DdNode const* elseThen;
@@ -572,13 +680,52 @@ namespace storm {
                 }
                 
                 // Visit else-else.
-                toMatrixRec(elseElse, rowIndications, columnsAndValues, rowOdd.getElseSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
+                toMatrixRec(elseElse, rowIndications, columnsAndValues, rowGroupOffsets, rowOdd.getElseSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
                 // Visit else-then.
-                toMatrixRec(elseThen, rowIndications, columnsAndValues, rowOdd.getElseSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
+                toMatrixRec(elseThen, rowIndications, columnsAndValues, rowGroupOffsets, rowOdd.getElseSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset, currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
                 // Visit then-else.
-                toMatrixRec(thenElse, rowIndications, columnsAndValues, rowOdd.getThenSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
+                toMatrixRec(thenElse, rowIndications, columnsAndValues, rowGroupOffsets, rowOdd.getThenSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
                 // Visit then-then.
-                toMatrixRec(thenThen, rowIndications, columnsAndValues, rowOdd.getThenSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
+                toMatrixRec(thenThen, rowIndications, columnsAndValues, rowGroupOffsets, rowOdd.getThenSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
+            }
+        }
+        
+        void Dd<DdType::CUDD>::splitGroupsRec(DdNode* dd, std::vector<Dd<DdType::CUDD>>& groups, std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::set<std::string> const& remainingMetaVariables) const {
+            // For the empty DD, we do not need to create a group.
+            if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
+                return;
+            }
+            
+            if (currentLevel == maxLevel) {
+                groups.push_back(Dd<DdType::CUDD>(this->getDdManager(), ADD(this->getDdManager()->getCuddManager(), dd), remainingMetaVariables));
+            } else if (ddGroupVariableIndices[currentLevel] < dd->index) {
+                splitGroupsRec(dd, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel, remainingMetaVariables);
+                splitGroupsRec(dd, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel, remainingMetaVariables);
+            } else {
+                splitGroupsRec(Cudd_E(dd), groups, ddGroupVariableIndices, currentLevel + 1, maxLevel, remainingMetaVariables);
+                splitGroupsRec(Cudd_T(dd), groups, ddGroupVariableIndices, currentLevel + 1, maxLevel, remainingMetaVariables);
+            }
+        }
+        
+        template<typename ValueType>
+        void Dd<DdType::CUDD>::addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<ValueType>& targetVector) const {
+            // For the empty DD, we do not need to add any entries.
+            if (dd == this->getDdManager()->getZero().getCuddAdd().getNode()) {
+                return;
+            }
+            
+            // If we are at the maximal level, the value to be set is stored as a constant in the DD.
+            if (currentLevel == maxLevel) {
+                targetVector[currentOffset] += static_cast<ValueType>(Cudd_V(dd));
+            } else if (ddVariableIndices[currentLevel] < dd->index) {
+                // If we skipped a level, we need to enumerate the explicit entries for the case in which the bit is set
+                // and for the one in which it is not set.
+                addToVectorRec(dd, currentLevel + 1, maxLevel, currentOffset, odd.getElseSuccessor(), ddVariableIndices, targetVector);
+                addToVectorRec(dd, currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), odd.getThenSuccessor(), ddVariableIndices, targetVector);
+            } else {
+                // Otherwise, we simply recursively call the function for both (different) cases.
+                addToVectorRec(Cudd_E(dd), currentLevel + 1, maxLevel, currentOffset, odd.getElseSuccessor(), ddVariableIndices, targetVector);
+                addToVectorRec(Cudd_T(dd), currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), odd.getThenSuccessor(), ddVariableIndices, targetVector);
             }
         }
         
@@ -733,6 +880,13 @@ namespace storm {
             dd.exportToDot();
             return out;
         }
-
+        
+        // Explicitly instantiate some templated functions.
+        template std::vector<double> Dd<DdType::CUDD>::toVector() const;
+        template std::vector<double> Dd<DdType::CUDD>::toVector(Odd<DdType::CUDD> const& rowOdd) const;
+        template void Dd<DdType::CUDD>::addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<double>& targetVector) const;
+        template std::vector<uint_fast64_t> Dd<DdType::CUDD>::toVector() const;
+        template std::vector<uint_fast64_t> Dd<DdType::CUDD>::toVector(Odd<DdType::CUDD> const& rowOdd) const;
+        template void Dd<DdType::CUDD>::addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<uint_fast64_t>& targetVector) const;
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h
index 045f547a0..316e30c89 100644
--- a/src/storage/dd/CuddDd.h
+++ b/src/storage/dd/CuddDd.h
@@ -458,25 +458,67 @@ namespace storm {
             uint_fast64_t getIndex() const;
             
             /*!
-             * Converts the DD to a double vector.
+             * Converts the DD to a vector.
              *
              * @return The double vector that is represented by this DD.
              */
-            std::vector<double> toVector() const;
+            template<typename ValueType>
+            std::vector<ValueType> toVector() const;
+
+            /*!
+             * Converts the DD to a vector. The given offset-labeled DD is used to determine the correct row of
+             * each entry.
+             *
+             * @param rowOdd The ODD used for determining the correct row.
+             * @return The double vector that is represented by this DD.
+             */
+            template<typename ValueType>
+            std::vector<ValueType> toVector(storm::dd::Odd<DdType::CUDD> const& rowOdd) const;
             
             /*!
              * Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
              * row, whereas all primed variables are assumed to encode the column.
+             *
+             * @return The matrix that is represented by this DD.
              */
             storm::storage::SparseMatrix<double> toMatrix() const;
+
+            /*!
+             * Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
+             * row, whereas all primed variables are assumed to encode the column. The given offset-labeled DDs are used
+             * to determine the correct row and column, respectively, for each entry.
+             *
+             * @param rowOdd The ODD used for determining the correct row.
+             * @param columnOdd The ODD used for determining the correct column.
+             * @return The matrix that is represented by this DD.
+             */
+            storm::storage::SparseMatrix<double> toMatrix(storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
+
+            /*!
+             * Converts the DD to a (sparse) double matrix. The given offset-labeled DDs are used to determine the
+             * correct row and column, respectively, for each entry.
+             *
+             * @param rowMetaVariables The meta variables that encode the rows of the matrix.
+             * @param columnMetaVariables The meta variables that encode the columns of the matrix.
+             * @param rowOdd The ODD used for determining the correct row.
+             * @param columnOdd The ODD used for determining the correct column.
+             * @return The matrix that is represented by this DD.
+             */
+            storm::storage::SparseMatrix<double> toMatrix(std::set<std::string> const& rowMetaVariables, std::set<std::string> const& columnMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
             
             /*!
-             * Converts the DD to a double vector using the given ODD (that needs to be constructed for the DD).
+             * Converts the DD to a row-grouped (sparse) double matrix. The given offset-labeled DDs are used to
+             * determine the correct row and column, respectively, for each entry. Note: this function assumes that
+             * the meta variables used to distinguish different row groups are at the very top of the DD.
              *
-             * @param odd The ODD for the DD.
-             * @return The double vector that is represented by this DD.
+             * @param rowMetaVariables The meta variables that encode the rows of the matrix.
+             * @param columnMetaVariables The meta variables that encode the columns of the matrix.
+             * @param groupMetaVariables The meta variables that are used to distinguish different row groups.
+             * @param rowOdd The ODD used for determining the correct row.
+             * @param columnOdd The ODD used for determining the correct column.
+             * @return The matrix that is represented by this DD.
              */
-            std::vector<double> toVector(Odd<DdType::CUDD> const& odd) const;
+            storm::storage::SparseMatrix<double> toMatrix(std::set<std::string> const& rowMetaVariables, std::set<std::string> const& columnMetaVariables, std::set<std::string> const& groupMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
             
             /*!
              * Retrieves whether the given meta variable is contained in the DD.
@@ -618,20 +660,6 @@ namespace storm {
              */
             Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
             
-            /*!
-             * Helper function to convert the DD into a double vector.
-             *
-             * @param dd The DD to convert.
-             * @param result The resulting vector whose entries are to be set appropriately. This vector needs to be
-             * preallocated.
-             * @param odd The ODD used for the translation.
-             * @param currentLevel The currently considered level in the DD.
-             * @param maxLevel The number of levels that need to be considered.
-             * @param currentOffset The current offset.
-             * @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
-             */
-            void toVectorRec(DdNode const* dd, std::vector<double>& result, Odd<DdType::CUDD> const& odd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, std::vector<uint_fast64_t> const& ddVariableIndices) const;
-            
             /*!
              * Helper function to convert the DD into a (sparse) matrix.
              *
@@ -643,6 +671,7 @@ namespace storm {
              * need to be restored afterwards.
              * @param columnsAndValues The vector that will hold the columns and values of non-zero entries upon successful
              * completion.
+             * @param rowGroupOffsets The row offsets at which a given row group starts.
              * @param rowOdd The ODD used for the row translation.
              * @param columnOdd The ODD used for the column translation.
              * @param currentRowLevel The currently considered row level in the DD.
@@ -656,7 +685,33 @@ namespace storm {
              * only works if the offsets given in rowIndications are already correct. If they need to be computed first,
              * this flag needs to be false.
              */
-            void toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<double>>& columnsAndValues, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues = true) const;
+            void toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<double>>& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupOffsets, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues = true) const;
+            
+            /*!
+             * Splits the given matrix DD into the groups using the given group variables.
+             *
+             * @param dd The DD to split.
+             * @param groups A vector that is to be filled with the DDs for the individual groups.
+             * @param ddGroupVariableIndices The (sorted) indices of all DD group variables that need to be considered.
+             * @param currentLevel The currently considered level in the DD.
+             * @param maxLevel The number of levels that need to be considered.
+             * @param remainingMetaVariables The meta variables that remain in the DDs after the groups have been split.
+             */
+            void splitGroupsRec(DdNode* dd, std::vector<Dd<DdType::CUDD>>& groups, std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::set<std::string> const& remainingMetaVariables) const;
+            
+            /*!
+             * Performs a recursive step to add the given DD-based vector to the given explicit vector.
+             *
+             * @param dd The DD to add to the explicit vector.
+             * @param currentLevel The currently considered level in the DD.
+             * @param maxLevel The number of levels that need to be considered.
+             * @param currentOffset The current offset.
+             * @param odd The ODD used for the translation.
+             * @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
+             * @param targetVector The vector to which the translated DD-based vector is to be added.
+             */
+            template<typename ValueType>
+            void addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<ValueType>& targetVector) const;
             
             /*!
              * Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
diff --git a/test/functional/storage/CuddDdTest.cpp b/test/functional/storage/CuddDdTest.cpp
index 98a528b3d..e95348625 100644
--- a/test/functional/storage/CuddDdTest.cpp
+++ b/test/functional/storage/CuddDdTest.cpp
@@ -380,6 +380,7 @@ TEST(CuddDd, ToExpressionTest) {
 
 TEST(CuddDd, OddTest) {
     std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
+    manager->addMetaVariable("a");
     manager->addMetaVariable("x", 1, 9);
     
     storm::dd::Dd<storm::dd::DdType::CUDD> dd = manager->getIdentity("x");
@@ -389,17 +390,34 @@ TEST(CuddDd, OddTest) {
     EXPECT_EQ(12, odd.getNodeCount());
 
     std::vector<double> ddAsVector;
-    ASSERT_NO_THROW(ddAsVector = dd.toVector());
+    ASSERT_NO_THROW(ddAsVector = dd.toVector<double>());
     EXPECT_EQ(9, ddAsVector.size());
     for (uint_fast64_t i = 0; i < ddAsVector.size(); ++i) {
         EXPECT_TRUE(i+1 == ddAsVector[i]);
     }
     
+    // Create a non-trivial matrix.
     dd = manager->getIdentity("x").equals(manager->getIdentity("x'")) * manager->getRange("x");
     dd += manager->getEncoding("x", 1) * manager->getRange("x'") + manager->getEncoding("x'", 1) * manager->getRange("x");
+    
+    // Create the ODDs.
+    storm::dd::Odd<storm::dd::DdType::CUDD> rowOdd;
+    ASSERT_NO_THROW(rowOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange("x")));
+    storm::dd::Odd<storm::dd::DdType::CUDD> columnOdd;
+    ASSERT_NO_THROW(columnOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange("x'")));
+    
+    // Try to translate the matrix.
     storm::storage::SparseMatrix<double> matrix;
-    ASSERT_NO_THROW(matrix = dd.toMatrix());
+    ASSERT_NO_THROW(matrix = dd.toMatrix({"x"}, {"x'"}, rowOdd, columnOdd));
+    
     EXPECT_EQ(9, matrix.getRowCount());
     EXPECT_EQ(9, matrix.getColumnCount());
     EXPECT_EQ(25, matrix.getNonzeroEntryCount());
+    
+    dd = manager->getRange("x") * manager->getRange("x'") * manager->getEncoding("a", 0).ite(dd, dd + manager->getConstant(1));
+    ASSERT_NO_THROW(matrix = dd.toMatrix({"x"}, {"x'"}, {"a"}, rowOdd, columnOdd));
+    EXPECT_EQ(18, matrix.getRowCount());
+    EXPECT_EQ(9, matrix.getRowGroupCount());
+    EXPECT_EQ(9, matrix.getColumnCount());
+    EXPECT_EQ(106, matrix.getNonzeroEntryCount());
 }
\ No newline at end of file

From 671797738aea3e58313f51075f3629047ecba38c Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 27 Jun 2014 17:28:20 +0200
Subject: [PATCH 147/147] Now the parameter that is set for dynamic reordering
 actually gets passed to CUDD.

Former-commit-id: 46676dc9d1c6e9a0bcbe8a411a7580634d981c09
---
 src/storage/dd/CuddDdManager.cpp | 56 +++++++++++++++++++++++++++++---
 src/storage/dd/CuddDdManager.h   |  3 ++
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp
index 3f0a2abed..f265a9f6a 100644
--- a/src/storage/dd/CuddDdManager.cpp
+++ b/src/storage/dd/CuddDdManager.cpp
@@ -16,25 +16,73 @@ bool CuddOptionsRegistered = storm::settings::Settings::registerNewModule([] (st
     // Set up option for reordering.
     std::vector<std::string> reorderingTechniques;
     reorderingTechniques.push_back("none");
+    reorderingTechniques.push_back("random");
+    reorderingTechniques.push_back("randompivot");
     reorderingTechniques.push_back("sift");
+    reorderingTechniques.push_back("siftconv");
     reorderingTechniques.push_back("ssift");
+    reorderingTechniques.push_back("ssiftconv");
     reorderingTechniques.push_back("gsift");
+    reorderingTechniques.push_back("gsiftconv");
     reorderingTechniques.push_back("win2");
+    reorderingTechniques.push_back("win2conv");
     reorderingTechniques.push_back("win3");
+    reorderingTechniques.push_back("win3conv");
     reorderingTechniques.push_back("win4");
+    reorderingTechniques.push_back("win4conv");
     reorderingTechniques.push_back("annealing");
     reorderingTechniques.push_back("genetic");
     reorderingTechniques.push_back("exact");
-	instance->addOption(storm::settings::OptionBuilder("Cudd", "reorder", "", "Sets the reordering technique used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used by Cudd's reordering routines. Must be in {\"none\", \"sift\", \"ssift\", \"gsift\", \"win2\", \"win3\", \"win4\", \"annealing\", \"genetic\", \"exact\"}.").setDefaultValueString("gsift").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(reorderingTechniques)).build()).build());
+	instance->addOption(storm::settings::OptionBuilder("Cudd", "reorder", "", "Sets the reordering technique used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used by Cudd's reordering routines. Must be in {\"none\", \"random\", \"randompivot\", \"sift\", \"siftconv\", \"ssift\", \"ssiftconv\", \"gsift\", \"gsiftconv\", \"win2\", \"win2conv\", \"win3\", \"win3conv\", \"win4\", \"win4conv\", \"annealing\", \"genetic\", \"exact\"}.").setDefaultValueString("gsift").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(reorderingTechniques)).build()).build());
     
     return true;
 });
 
 namespace storm {
     namespace dd {
-        DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
+        DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager(), reorderingTechnique(CUDD_REORDER_NONE) {
             this->cuddManager.SetMaxMemory(static_cast<unsigned long>(storm::settings::Settings::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024ul * 1024ul));
             this->cuddManager.SetEpsilon(storm::settings::Settings::getInstance()->getOptionByLongName("cuddprec").getArgument(0).getValueAsDouble());
+            
+            // Now set the selected reordering technique.
+            std::string const& reorderingTechnique = storm::settings::Settings::getInstance()->getOptionByLongName("reorder").getArgument(0).getValueAsString();
+            if (reorderingTechnique == "none") {
+                this->reorderingTechnique = CUDD_REORDER_NONE;
+            } else if (reorderingTechnique == "random") {
+                this->reorderingTechnique = CUDD_REORDER_RANDOM;
+            } else if (reorderingTechnique == "randompivot") {
+                this->reorderingTechnique = CUDD_REORDER_RANDOM_PIVOT;
+            } else if (reorderingTechnique == "sift") {
+                this->reorderingTechnique = CUDD_REORDER_SIFT;
+            } else if (reorderingTechnique == "siftconv") {
+                this->reorderingTechnique = CUDD_REORDER_SIFT_CONVERGE;
+            } else if (reorderingTechnique == "ssift") {
+                this->reorderingTechnique = CUDD_REORDER_SYMM_SIFT;
+            } else if (reorderingTechnique == "ssiftconv") {
+                this->reorderingTechnique = CUDD_REORDER_SYMM_SIFT_CONV;
+            } else if (reorderingTechnique == "gsift") {
+                this->reorderingTechnique = CUDD_REORDER_GROUP_SIFT;
+            } else if (reorderingTechnique == "gsiftconv") {
+                this->reorderingTechnique = CUDD_REORDER_GROUP_SIFT_CONV;
+            } else if (reorderingTechnique == "win2") {
+                this->reorderingTechnique = CUDD_REORDER_WINDOW2;
+            } else if (reorderingTechnique == "win2conv") {
+                this->reorderingTechnique = CUDD_REORDER_WINDOW2_CONV;
+            } else if (reorderingTechnique == "win3") {
+                this->reorderingTechnique = CUDD_REORDER_WINDOW3;
+            } else if (reorderingTechnique == "win3conv") {
+                this->reorderingTechnique = CUDD_REORDER_WINDOW3_CONV;
+            } else if (reorderingTechnique == "win4") {
+                this->reorderingTechnique = CUDD_REORDER_WINDOW4;
+            } else if (reorderingTechnique == "win4conv") {
+                this->reorderingTechnique = CUDD_REORDER_WINDOW4_CONV;
+            } else if (reorderingTechnique == "annealing") {
+                this->reorderingTechnique = CUDD_REORDER_ANNEALING;
+            } else if (reorderingTechnique == "genetic") {
+                this->reorderingTechnique = CUDD_REORDER_GENETIC;
+            } else if (reorderingTechnique == "exact") {
+                this->reorderingTechnique = CUDD_REORDER_EXACT;
+            }
         }
         
         Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() {
@@ -208,7 +256,7 @@ namespace storm {
         
         void DdManager<DdType::CUDD>::allowDynamicReordering(bool value) {
             if (value) {
-                this->getCuddManager().AutodynEnable(CUDD_REORDER_GROUP_SIFT_CONV);
+                this->getCuddManager().AutodynEnable(this->reorderingTechnique);
             } else {
                 this->getCuddManager().AutodynDisable();
             }
@@ -220,7 +268,7 @@ namespace storm {
         }
         
         void DdManager<DdType::CUDD>::triggerReordering() {
-            this->getCuddManager().ReduceHeap(CUDD_REORDER_GROUP_SIFT_CONV, 0);
+            this->getCuddManager().ReduceHeap(this->reorderingTechnique, 0);
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h
index 75c6a23de..682fb4c8b 100644
--- a/src/storage/dd/CuddDdManager.h
+++ b/src/storage/dd/CuddDdManager.h
@@ -174,6 +174,9 @@ namespace storm {
             
             // The manager responsible for the DDs created/modified with this DdManager.
             Cudd cuddManager;
+            
+            // The technique that is used for dynamic reordering.
+            Cudd_ReorderingType reorderingTechnique;
         };
     }
 }