From e43dfc278409729580d78ce4f9a4a8a527d4e4c6 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 11 Aug 2016 16:24:43 +0200
Subject: [PATCH 01/20] removed unused setting

Former-commit-id: 18a91c2acb82ec553b91370047e20e4ef3872281
---
 src/settings/modules/CoreSettings.cpp | 5 -----
 src/settings/modules/CoreSettings.h   | 1 -
 2 files changed, 6 deletions(-)

diff --git a/src/settings/modules/CoreSettings.cpp b/src/settings/modules/CoreSettings.cpp
index b42a301c8..5a6dfc9c0 100644
--- a/src/settings/modules/CoreSettings.cpp
+++ b/src/settings/modules/CoreSettings.cpp
@@ -30,7 +30,6 @@ namespace storm {
             const std::string CoreSettings::engineOptionShortName = "e";
             const std::string CoreSettings::ddLibraryOptionName = "ddlib";
             const std::string CoreSettings::cudaOptionName = "cuda";
-			const std::string CoreSettings::minMaxEquationSolvingTechniqueOptionName = "ndmethod";
             
             CoreSettings::CoreSettings() : ModuleSettings(moduleName), engine(CoreSettings::Engine::Sparse) {
                 this->addOption(storm::settings::OptionBuilder(moduleName, counterexampleOptionName, false, "Generates a counterexample for the given PRCTL formulas if not satisfied by the model")
@@ -57,10 +56,6 @@ namespace storm {
                                 .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of an SMT solver. Available are: z3 and mathsat.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(smtSolvers)).setDefaultValueString("z3").build()).build());
                 this->addOption(storm::settings::OptionBuilder(moduleName, statisticsOptionName, false, "Sets whether to display statistics if available.").setShortName(statisticsOptionShortName).build());
                 this->addOption(storm::settings::OptionBuilder(moduleName, cudaOptionName, false, "Sets whether to use CUDA to speed up computation time.").build());
-
-				std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration"};
-				this->addOption(storm::settings::OptionBuilder(moduleName, minMaxEquationSolvingTechniqueOptionName, false, "Sets which min/max linear equation solving technique is preferred.")
-					.addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a min/max linear equation solving technique. Available are: value-iteration (vi) and policy-iteration (pi).").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(minMaxSolvingTechniques)).setDefaultValueString("vi").build()).build());
             }
 
             bool CoreSettings::isCounterexampleSet() const {
diff --git a/src/settings/modules/CoreSettings.h b/src/settings/modules/CoreSettings.h
index 9b7189e2c..f6c8fbdf2 100644
--- a/src/settings/modules/CoreSettings.h
+++ b/src/settings/modules/CoreSettings.h
@@ -151,7 +151,6 @@ namespace storm {
                 static const std::string engineOptionShortName;
                 static const std::string ddLibraryOptionName;
                 static const std::string cudaOptionName;
-                static const std::string minMaxEquationSolvingTechniqueOptionName;
             };
 
         } // namespace modules

From 7ab88457a71851fe7d1245d0aedebac1c4fdff5c Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 11 Aug 2016 18:07:58 +0200
Subject: [PATCH 02/20] corrected reference to wrong settings module

Former-commit-id: 2f35b2dc82efbb76fed5fb17696a13599d9fadd7
---
 src/storm.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/storm.cpp b/src/storm.cpp
index 0d23f9ecc..236d15a7b 100644
--- a/src/storm.cpp
+++ b/src/storm.cpp
@@ -6,6 +6,7 @@
 #include "src/utility/initialize.h"
 
 #include "src/settings/SettingsManager.h"
+#include "src/settings/modules/GeneralSettings.h"
 
 /*!
  * Main entry point of the executable storm.
@@ -13,7 +14,7 @@
 int main(const int argc, const char** argv) {
 
     try {
-        auto starttime = std::chrono::high_resolution_clock::now();
+        auto start = std::chrono::high_resolution_clock::now();
         storm::utility::setUp();
         storm::cli::printHeader("Storm", argc, argv);
         storm::settings::initializeAll("Storm", "storm");
@@ -27,11 +28,11 @@ int main(const int argc, const char** argv) {
         
         // All operations have now been performed, so we clean up everything and terminate.
         storm::utility::cleanUp();
-        auto endtime = std::chrono::high_resolution_clock::now();
-        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endtime-starttime);
-        auto durationSec = std::chrono::duration_cast<std::chrono::seconds>(endtime-starttime);
-        if(storm::settings::getModule<storm::settings::modules::IOSettings>().isPrintTimingsSet()) {
-            std::cout << "Overal runtime: " << duration.count() << " ms. ( approx " << durationSec.count() << " seconds)." << std::endl;
+        auto end = std::chrono::high_resolution_clock::now();
+        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
+        auto durationSec = std::chrono::duration_cast<std::chrono::seconds>(end - start);
+        if(storm::settings::getModule<storm::settings::modules::GeneralSettings>().isPrintTimingsSet()) {
+            std::cout << "Overal runtime: " << duration.count() << " ms. (approximately " << durationSec.count() << " seconds)." << std::endl;
         }
         return 0;
     } catch (storm::exceptions::BaseException const& exception) {

From 569b27e11055cb63a1c7c183d1abeff743a242ea Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 15 Aug 2016 14:49:21 +0200
Subject: [PATCH 03/20] work towards having rational numbers instead of doubles
 as literals in expressions

Former-commit-id: c62f8af0612a5cc4c351d79cd224f6439b523e99
---
 src/adapters/AddExpressionAdapter.cpp         |  2 +-
 src/adapters/MathsatExpressionAdapter.h       |  2 +-
 .../expressions/DoubleLiteralExpression.cpp   | 16 ++++-
 .../expressions/DoubleLiteralExpression.h     | 25 ++++++--
 .../expressions/LinearCoefficientVisitor.cpp  |  2 +-
 .../expressions/ToRationalFunctionVisitor.cpp |  3 +-
 .../expressions/ToRationalNumberVisitor.cpp   | 29 ++++++---
 src/utility/constants.cpp                     | 61 ++++++++++++++++---
 src/utility/constants.h                       |  3 +
 9 files changed, 114 insertions(+), 29 deletions(-)

diff --git a/src/adapters/AddExpressionAdapter.cpp b/src/adapters/AddExpressionAdapter.cpp
index e50620db8..7a22c8f8f 100644
--- a/src/adapters/AddExpressionAdapter.cpp
+++ b/src/adapters/AddExpressionAdapter.cpp
@@ -195,7 +195,7 @@ namespace storm {
         
         template<storm::dd::DdType Type, typename ValueType>
         boost::any AddExpressionAdapter<Type, ValueType>::visit(storm::expressions::DoubleLiteralExpression const& expression) {
-            return ddManager->getConstant(static_cast<ValueType>(expression.getValue()));
+            return ddManager->getConstant(static_cast<ValueType>(expression.getValueAsDouble()));
         }
         
         // Explicitly instantiate the symbolic expression adapter
diff --git a/src/adapters/MathsatExpressionAdapter.h b/src/adapters/MathsatExpressionAdapter.h
index 9fec0cf15..db5bf9b69 100644
--- a/src/adapters/MathsatExpressionAdapter.h
+++ b/src/adapters/MathsatExpressionAdapter.h
@@ -172,7 +172,7 @@ namespace storm {
 			}
 
 			virtual boost::any visit(expressions::DoubleLiteralExpression const& expression) override {
-				return msat_make_number(env, std::to_string(expression.getValue()).c_str());
+				return msat_make_number(env, std::to_string(expression.getValueAsDouble()).c_str());
 			}
 
 			virtual boost::any visit(expressions::IntegerLiteralExpression const& expression) override {
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index cab9fc31b..192d747ee 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -2,14 +2,20 @@
 #include "src/storage/expressions/ExpressionManager.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 
+#include "src/utility/constants.h"
+
 namespace storm {
     namespace expressions {
-        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, double value) : BaseExpression(manager, manager.getRationalType()), value(value) {
+        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, double value) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(value)) {
+            // Intentionally left empty.
+        }
+        
+        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(valueAsString)) {
             // Intentionally left empty.
         }
         
         double DoubleLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
-            return this->getValue();
+            return this->getValueAsDouble();
         }
         
         bool DoubleLiteralExpression::isLiteral() const {
@@ -28,7 +34,11 @@ namespace storm {
             return visitor.visit(*this);
         }
         
-        double DoubleLiteralExpression::getValue() const {
+        double DoubleLiteralExpression::getValueAsDouble() const {
+            return storm::utility::convertNumber<double>(this->value);
+        }
+        
+        storm::RationalNumber DoubleLiteralExpression::getValue() const {
             return this->value;
         }
         
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index 676291a77..6a04f23e3 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -4,6 +4,8 @@
 #include "src/storage/expressions/BaseExpression.h"
 #include "src/utility/OsDetection.h"
 
+#include "src/adapters/CarlAdapter.h"
+
 namespace storm {
     namespace expressions {
         class DoubleLiteralExpression : public BaseExpression {
@@ -15,7 +17,15 @@ namespace storm {
              * @param value The value of the double literal.
              */
             DoubleLiteralExpression(ExpressionManager const& manager, double value);
-            
+
+            /*!
+             * Creates an double literal expression with the value given as a string.
+             *
+             * @param manager The manager responsible for this expression.
+             * @param value The string representation of the value of the literal.
+             */
+            DoubleLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString);
+
             // Instantiate constructors and assignments with their default implementations.
             DoubleLiteralExpression(DoubleLiteralExpression const& other) = default;
             DoubleLiteralExpression& operator=(DoubleLiteralExpression const& other) = delete;
@@ -37,15 +47,22 @@ namespace storm {
              *
              * @return The value of the double literal.
              */
-            double getValue() const;
+            double getValueAsDouble() const;
+
+            /*!
+             * Retrieves the value of the double literal.
+             *
+             * @return The value of the double literal.
+             */
+            storm::RationalNumber getValue() const;
             
         protected:
             // Override base class method.
             virtual void printToStream(std::ostream& stream) const override;
             
         private:
-            // The value of the double literal.
-            double value;
+            // The value of the literal.
+            storm::RationalNumber value;
         };
     }
 }
diff --git a/src/storage/expressions/LinearCoefficientVisitor.cpp b/src/storage/expressions/LinearCoefficientVisitor.cpp
index 8d7f39278..3d881c25e 100644
--- a/src/storage/expressions/LinearCoefficientVisitor.cpp
+++ b/src/storage/expressions/LinearCoefficientVisitor.cpp
@@ -152,7 +152,7 @@ namespace storm {
         }
         
         boost::any LinearCoefficientVisitor::visit(DoubleLiteralExpression const& expression) {
-            return VariableCoefficients(expression.getValue());
+            return VariableCoefficients(expression.getValueAsDouble());
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/ToRationalFunctionVisitor.cpp b/src/storage/expressions/ToRationalFunctionVisitor.cpp
index 1a3dd0fc3..533fa1f1f 100644
--- a/src/storage/expressions/ToRationalFunctionVisitor.cpp
+++ b/src/storage/expressions/ToRationalFunctionVisitor.cpp
@@ -2,6 +2,7 @@
 
 #include <sstream>
 
+#include "src/utility/constants.h"
 #include "src/utility/macros.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
@@ -93,7 +94,7 @@ namespace storm {
         
         template<typename RationalFunctionType>
         boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(DoubleLiteralExpression const& expression) {
-            return RationalFunctionType(carl::rationalize<storm::RationalNumber>(expression.getValue()));
+            return storm::utility::convertNumber<storm::RationalFunction>(expression.getValue());
         }
 
         template class ToRationalFunctionVisitor<storm::RationalFunction>;
diff --git a/src/storage/expressions/ToRationalNumberVisitor.cpp b/src/storage/expressions/ToRationalNumberVisitor.cpp
index 785f36950..44194cb4b 100644
--- a/src/storage/expressions/ToRationalNumberVisitor.cpp
+++ b/src/storage/expressions/ToRationalNumberVisitor.cpp
@@ -1,6 +1,7 @@
 #include "src/storage/expressions/ToRationalNumberVisitor.h"
 
 #include "src/utility/macros.h"
+#include "src/utility/constants.h"
 #include "src/exceptions/InvalidArgumentException.h"
 #include "src/exceptions/NotSupportedException.h"
 
@@ -28,26 +29,36 @@ namespace storm {
         
         template<typename RationalNumberType>
         boost::any ToRationalNumberVisitor<RationalNumberType>::visit(BinaryNumericalFunctionExpression const& expression) {
-            RationalNumberType firstOperandAsRationalFunction = boost::any_cast<RationalNumberType>(expression.getFirstOperand()->accept(*this));
-            RationalNumberType secondOperandAsRationalFunction = boost::any_cast<RationalNumberType>(expression.getSecondOperand()->accept(*this));
+            RationalNumberType firstOperandAsRationalNumber = boost::any_cast<RationalNumberType>(expression.getFirstOperand()->accept(*this));
+            RationalNumberType secondOperandAsRationalNumber = boost::any_cast<RationalNumberType>(expression.getSecondOperand()->accept(*this));
             switch(expression.getOperatorType()) {
                 case BinaryNumericalFunctionExpression::OperatorType::Plus:
-                    return firstOperandAsRationalFunction + secondOperandAsRationalFunction;
+                    return firstOperandAsRationalNumber + secondOperandAsRationalNumber;
                     break;
                 case BinaryNumericalFunctionExpression::OperatorType::Minus:
-                    return firstOperandAsRationalFunction - secondOperandAsRationalFunction;
+                    return firstOperandAsRationalNumber - secondOperandAsRationalNumber;
                     break;
                 case BinaryNumericalFunctionExpression::OperatorType::Times:
-                    return firstOperandAsRationalFunction * secondOperandAsRationalFunction;
+                    return firstOperandAsRationalNumber * secondOperandAsRationalNumber;
                     break;
                 case BinaryNumericalFunctionExpression::OperatorType::Divide:
-                    return firstOperandAsRationalFunction / secondOperandAsRationalFunction;
+                    return firstOperandAsRationalNumber / secondOperandAsRationalNumber;
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Min:
+                    return std::min(firstOperandAsRationalNumber, secondOperandAsRationalNumber);
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Max:
+                    return std::max(firstOperandAsRationalNumber, secondOperandAsRationalNumber);
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Power:
+                    STORM_LOG_THROW(storm::utility::isInteger(secondOperandAsRationalNumber), storm::exceptions::InvalidArgumentException, "Exponent of power operator must be a positive integer.");
+                    uint_fast64_t exponentAsInteger = storm::utility::convertNumber<uint_fast64_t>(secondOperandAsRationalNumber);
+                    return storm::utility::pow(firstOperandAsRationalNumber, exponentAsInteger);
                     break;
-                default:
-                    STORM_LOG_ASSERT(false, "Illegal operator type.");
             }
             
             // Return a dummy. This point must, however, never be reached.
+            STORM_LOG_ASSERT(false, "Illegal operator type.");
             return boost::any();
         }
         
@@ -88,7 +99,7 @@ namespace storm {
         template<typename RationalNumberType>
         boost::any ToRationalNumberVisitor<RationalNumberType>::visit(DoubleLiteralExpression const& expression) {
 #ifdef STORM_HAVE_CARL
-            return RationalNumberType(carl::rationalize<storm::RationalNumber>(expression.getValue()));
+            return expression.getValue();
 #else
             STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Rational numbers are not supported in this build.");
 #endif
diff --git a/src/utility/constants.cpp b/src/utility/constants.cpp
index 71d56cd63..2630ed285 100644
--- a/src/utility/constants.cpp
+++ b/src/utility/constants.cpp
@@ -39,6 +39,23 @@ namespace storm {
         bool isConstant(ValueType const& a) {
             return true;
         }
+        
+        template<typename ValueType>
+        bool isInteger(ValueType const& number) {
+            ValueType iPart;
+            ValueType result = std::modf(number, &iPart);
+            return result = zero<ValueType>();
+        }
+
+        template<>
+        bool isInteger(int const& number) {
+            return true;
+        }
+
+        template<>
+        bool isInteger(uint_fast64_t const& number) {
+            return true;
+        }
 
 #ifdef STORM_HAVE_CARL
         template<>
@@ -50,7 +67,6 @@ namespace storm {
         bool isZero(storm::RationalNumber const& a) {
             return carl::isZero(a);
         }
-
         
         template<>
         bool isOne(storm::RationalFunction const& a) {
@@ -93,6 +109,12 @@ namespace storm {
         	// FIXME: this should be treated more properly.
         	return storm::RationalNumber(-1);
         }
+        
+        template<>
+        bool isInteger(storm::RationalNumber const& number) {
+            return carl::isInteger(number);
+        }
+
 #endif
         
         template<typename ValueType>
@@ -102,9 +124,9 @@ namespace storm {
 
         template<typename ValueType>
         ValueType simplify(ValueType value) {
-        // In the general case, we don't do anything here, but merely return the value. If something else is
-        // supposed to happen here, the templated function can be specialized for this particular type.
-                return value;
+            // In the general case, we don't do anything here, but merely return the value. If something else is
+            // supposed to happen here, the templated function can be specialized for this particular type.
+            return value;
         }
         
         template<>
@@ -151,7 +173,12 @@ namespace storm {
         double convertNumber(RationalNumber const& number){
             return carl::toDouble(number);
         }
-        
+
+        template<>
+        uint_fast64_t convertNumber(RationalNumber const& number){
+            return carl::toInt<unsigned long>(number);
+        }
+
         template<>
         RationalNumber convertNumber(double const& number){
             return carl::rationalize<RationalNumber>(number);
@@ -167,15 +194,26 @@ namespace storm {
             return RationalFunction(carl::rationalize<RationalNumber>(number));
         }
 
+        template<>
+        RationalNumber convertNumber(std::string const& number) {
+            return carl::rationalize<RationalNumber>(number);
+        }
+
         template<>
         RationalFunction convertNumber(RationalNumber const& number) {
             return RationalFunction(number);
         }
         
         template<>
-        storm::RationalNumber abs(storm::RationalNumber const& number) {
+        RationalNumber abs(storm::RationalNumber const& number) {
             return carl::abs(number);
         }
+        
+        template<>
+        RationalNumber pow(RationalNumber const& value, uint_fast64_t exponent) {
+            return carl::pow(value, exponent);
+        }
+
 #endif
 
         template<typename IndexType, typename ValueType>
@@ -214,6 +252,7 @@ namespace storm {
         template storm::storage::MatrixEntry<storm::storage::sparse::state_type, double>&& simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, double>&& matrixEntry);
 
         template double abs(double const& number);
+        template bool isInteger(double const& number);
         
         template bool isOne(float const& value);
         template bool isZero(float const& value);
@@ -224,6 +263,7 @@ namespace storm {
         template float infinity();
 
         template float pow(float const& value, uint_fast64_t exponent);
+        template bool isInteger(float const& number);
 
         template float simplify(float value);
 
@@ -240,7 +280,8 @@ namespace storm {
         template int infinity();
         
         template int pow(int const& value, uint_fast64_t exponent);
-        
+        template bool isInteger(int const& number);
+
         template int simplify(int value);
         
         template storm::storage::MatrixEntry<storm::storage::sparse::state_type, int> simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, int> matrixEntry);
@@ -278,12 +319,14 @@ namespace storm {
         template storm::RationalNumber infinity();
 
         template double convertNumber(storm::RationalNumber const& number);
+        template uint_fast64_t convertNumber(storm::RationalNumber const& number);
         template storm::RationalNumber convertNumber(double const& number);
         template storm::RationalNumber convertNumber(storm::RationalNumber const& number);
-
+        RationalNumber convertNumber(std::string const& number);
+        
         template storm::RationalNumber abs(storm::RationalNumber const& number);
 
-//        template storm::RationalNumber pow(storm::RationalNumber const& value, uint_fast64_t exponent);
+        template storm::RationalNumber pow(storm::RationalNumber const& value, uint_fast64_t exponent);
         
         template storm::RationalNumber simplify(storm::RationalNumber value);
         template storm::storage::MatrixEntry<storm::storage::sparse::state_type, storm::RationalNumber> simplify(storm::storage::MatrixEntry<storm::storage::sparse::state_type, storm::RationalNumber> matrixEntry);
diff --git a/src/utility/constants.h b/src/utility/constants.h
index 4ec4e7539..66edb9f46 100644
--- a/src/utility/constants.h
+++ b/src/utility/constants.h
@@ -56,6 +56,9 @@ namespace storm {
         
         template<typename ValueType>
         ValueType abs(ValueType const& number);
+        
+        template<typename ValueType>
+        bool isInteger(ValueType const& number);
     }
 }
 

From 7b2a667a9d28b0a81fef0f11116bb9dba652823d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 15 Aug 2016 16:53:56 +0200
Subject: [PATCH 04/20] double literal now stores rational internally

Former-commit-id: c0f089b8baa1c6bef553889fb708f8a44cae1937
---
 src/parser/ExpressionParser.cpp               | 32 +++++++++++++++++--
 src/parser/ExpressionParser.h                 | 16 ++++++++--
 .../expressions/DoubleLiteralExpression.cpp   |  4 +++
 .../expressions/DoubleLiteralExpression.h     |  8 +++++
 src/storage/expressions/ExpressionManager.cpp |  4 +++
 src/storage/expressions/ExpressionManager.h   |  9 ++++++
 6 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp
index 20982bd20..d556d799a 100644
--- a/src/parser/ExpressionParser.cpp
+++ b/src/parser/ExpressionParser.cpp
@@ -3,6 +3,34 @@
 #include "src/exceptions/InvalidTypeException.h"
 #include "src/exceptions/WrongFormatException.h"
 
+#include "src/utility/constants.h"
+
+namespace boost {
+    namespace spirit {
+        namespace traits {
+            template<>
+            bool scale(int exp, storm::RationalNumber& r, storm::RationalNumber acc) {
+                if (exp >= 0) {
+                    r = acc * storm::utility::pow(storm::RationalNumber(10), static_cast<uint_fast64_t>(exp));
+                } else {
+                    r = acc / storm::utility::pow(storm::RationalNumber(10), static_cast<uint_fast64_t>(-exp));
+                }
+                return true;
+            }
+            
+            template<>
+            bool is_equal_to_one(storm::RationalNumber const& value) {
+                return storm::utility::isOne(value);
+            }
+            
+            template<>
+            storm::RationalNumber negate(bool neg, storm::RationalNumber const& number) {
+                return neg ? storm::RationalNumber(-number) : number;
+            }
+        }
+    }
+}
+
 namespace storm {
     namespace parser {
         ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool enableErrorHandling, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), infixPowerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), prefixPowerOperator_(), trueFalse_(manager), manager(manager.getSharedPointer()), createExpressions(false), acceptDoubleLiterals(true), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
@@ -33,7 +61,7 @@ namespace storm {
 			identifierExpression = identifier[qi::_val = phoenix::bind(&ExpressionParser::getIdentifierExpression, phoenix::ref(*this), qi::_1, allowBacktracking, qi::_pass)];
             identifierExpression.name("identifier expression");
             
-            literalExpression = trueFalse_[qi::_val = qi::_1] | 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, qi::_pass)];
+            literalExpression = trueFalse_[qi::_val = qi::_1] | rationalLiteral_[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, qi::_pass)];
             literalExpression.name("literal expression");
             
             atomicExpression = floorCeilExpression | prefixPowerExpression | minMaxExpression | (qi::lit("(") >> expression >> qi::lit(")")) | literalExpression | identifierExpression;
@@ -295,7 +323,7 @@ namespace storm {
             return manager->boolean(false);
         }
                 
-        storm::expressions::Expression ExpressionParser::createDoubleLiteralExpression(double value, bool& pass) const {
+        storm::expressions::Expression ExpressionParser::createDoubleLiteralExpression(storm::RationalNumber const& 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;
diff --git a/src/parser/ExpressionParser.h b/src/parser/ExpressionParser.h
index 66d851707..c728e0b84 100644
--- a/src/parser/ExpressionParser.h
+++ b/src/parser/ExpressionParser.h
@@ -8,8 +8,20 @@
 #include "src/storage/expressions/Expression.h"
 #include "src/storage/expressions/ExpressionManager.h"
 
+#include "src/adapters/CarlAdapter.h"
+
 namespace storm {
     namespace parser {
+        template<typename NumberType>
+        struct RationalPolicies : boost::spirit::qi::strict_real_policies<NumberType> {
+            static const bool expect_dot = true;
+            
+            template <typename It, typename Attr>
+            static bool parse_nan(It&, It const&, Attr&) { return false; }
+            template <typename It, typename Attr>
+            static bool parse_inf(It&, It const&, Attr&) { return false; }
+        };
+        
         class ExpressionParser : public qi::grammar<Iterator, storm::expressions::Expression(), Skipper> {
         public:
             /*!
@@ -236,7 +248,7 @@ namespace storm {
             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;
+            boost::spirit::qi::real_parser<storm::RationalNumber, RationalPolicies<storm::RationalNumber>> rationalLiteral_;
             
             // Helper functions to create expressions.
             storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3, bool& pass) const;
@@ -248,7 +260,7 @@ namespace storm {
             storm::expressions::Expression createMultExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const;
             storm::expressions::Expression createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const;
             storm::expressions::Expression createUnaryExpression(boost::optional<storm::expressions::OperatorType> const& operatorType, storm::expressions::Expression const& e1, bool& pass) const;
-            storm::expressions::Expression createDoubleLiteralExpression(double value, bool& pass) const;
+            storm::expressions::Expression createDoubleLiteralExpression(storm::RationalNumber const& value, bool& pass) const;
             storm::expressions::Expression createIntegerLiteralExpression(int value, bool& pass) const;
             storm::expressions::Expression createMinimumMaximumExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const;
             storm::expressions::Expression createFloorCeilExpression(storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e1, bool& pass) const;
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index 192d747ee..86a2ba889 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -14,6 +14,10 @@ namespace storm {
             // Intentionally left empty.
         }
         
+        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value) : BaseExpression(manager, manager.getRationalType()), value(value) {
+            // Intentionally left empty.
+        }
+        
         double DoubleLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
             return this->getValueAsDouble();
         }
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index 6a04f23e3..1b6aa28b3 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -26,6 +26,14 @@ namespace storm {
              */
             DoubleLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString);
 
+            /*!
+             * Creates an double literal expression with the rational value.
+             *
+             * @param manager The manager responsible for this expression.
+             * @param value The rational number that is the value of this literal expression.
+             */
+            DoubleLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value);
+
             // Instantiate constructors and assignments with their default implementations.
             DoubleLiteralExpression(DoubleLiteralExpression const& other) = default;
             DoubleLiteralExpression& operator=(DoubleLiteralExpression const& other) = delete;
diff --git a/src/storage/expressions/ExpressionManager.cpp b/src/storage/expressions/ExpressionManager.cpp
index d1add4402..a92d908f3 100644
--- a/src/storage/expressions/ExpressionManager.cpp
+++ b/src/storage/expressions/ExpressionManager.cpp
@@ -68,6 +68,10 @@ namespace storm {
             return Expression(std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(*this, value)));
         }
         
+        Expression ExpressionManager::rational(storm::RationalNumber const& value) const {
+            return Expression(std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(*this, value)));
+        }
+        
         bool ExpressionManager::operator==(ExpressionManager const& other) const {
             return this == &other;
         }
diff --git a/src/storage/expressions/ExpressionManager.h b/src/storage/expressions/ExpressionManager.h
index 6fee92fd6..f3ec7e76b 100644
--- a/src/storage/expressions/ExpressionManager.h
+++ b/src/storage/expressions/ExpressionManager.h
@@ -10,6 +10,7 @@
 
 #include "src/storage/expressions/Variable.h"
 #include "src/storage/expressions/Expression.h"
+#include "src/adapters/CarlAdapter.h"
 #include "src/utility/OsDetection.h"
 
 namespace storm {
@@ -104,6 +105,14 @@ namespace storm {
              * @return The resulting expression.
              */
             Expression rational(double value) const;
+
+            /*!
+             * Creates an expression that characterizes the given rational literal.
+             *
+             * @param value The value of the rational literal.
+             * @return The resulting expression.
+             */
+            Expression rational(storm::RationalNumber const& value) const;
             
             /*!
              * Compares the two expression managers for equality, which holds iff they are the very same object.

From 58857d62ed395040aa69cbc6b3d1e6e789fa0744 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 15 Aug 2016 16:55:45 +0200
Subject: [PATCH 05/20] renamed double literal to rational literal

Former-commit-id: 7bafe79eed1fd06aa0254a20699454265ed0eeb2
---
 src/adapters/AddExpressionAdapter.cpp         |  2 +-
 src/adapters/AddExpressionAdapter.h           |  2 +-
 src/adapters/MathsatExpressionAdapter.h       |  2 +-
 src/adapters/Z3ExpressionAdapter.cpp          |  2 +-
 src/adapters/Z3ExpressionAdapter.h            |  2 +-
 src/parser/ExpressionParser.cpp               |  4 ++--
 src/parser/ExpressionParser.h                 |  2 +-
 .../BinaryNumericalFunctionExpression.cpp     |  4 ++--
 .../expressions/DoubleLiteralExpression.cpp   | 24 +++++++++----------
 .../expressions/DoubleLiteralExpression.h     | 24 +++++++++----------
 src/storage/expressions/ExpressionManager.cpp |  4 ++--
 src/storage/expressions/ExpressionVisitor.h   |  4 ++--
 src/storage/expressions/Expressions.h         |  2 +-
 .../expressions/LinearCoefficientVisitor.cpp  |  2 +-
 .../expressions/LinearCoefficientVisitor.h    |  2 +-
 .../expressions/LinearityCheckVisitor.cpp     |  2 +-
 .../expressions/LinearityCheckVisitor.h       |  2 +-
 .../expressions/SubstitutionVisitor.cpp       |  2 +-
 src/storage/expressions/SubstitutionVisitor.h |  2 +-
 .../expressions/ToExprtkStringVisitor.cpp     |  2 +-
 .../expressions/ToExprtkStringVisitor.h       |  2 +-
 .../expressions/ToRationalFunctionVisitor.cpp |  2 +-
 .../expressions/ToRationalFunctionVisitor.h   |  2 +-
 .../expressions/ToRationalNumberVisitor.cpp   |  2 +-
 .../expressions/ToRationalNumberVisitor.h     |  2 +-
 .../UnaryNumericalFunctionExpression.cpp      |  4 ++--
 26 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/src/adapters/AddExpressionAdapter.cpp b/src/adapters/AddExpressionAdapter.cpp
index 7a22c8f8f..2f0dc7190 100644
--- a/src/adapters/AddExpressionAdapter.cpp
+++ b/src/adapters/AddExpressionAdapter.cpp
@@ -194,7 +194,7 @@ namespace storm {
         }
         
         template<storm::dd::DdType Type, typename ValueType>
-        boost::any AddExpressionAdapter<Type, ValueType>::visit(storm::expressions::DoubleLiteralExpression const& expression) {
+        boost::any AddExpressionAdapter<Type, ValueType>::visit(storm::expressions::RationalLiteralExpression const& expression) {
             return ddManager->getConstant(static_cast<ValueType>(expression.getValueAsDouble()));
         }
         
diff --git a/src/adapters/AddExpressionAdapter.h b/src/adapters/AddExpressionAdapter.h
index 89d825d96..dfb13a315 100644
--- a/src/adapters/AddExpressionAdapter.h
+++ b/src/adapters/AddExpressionAdapter.h
@@ -31,7 +31,7 @@ namespace storm {
             virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(storm::expressions::BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(storm::expressions::IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(storm::expressions::DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(storm::expressions::RationalLiteralExpression const& expression) override;
 
         private:
             // The manager responsible for the DDs built by this adapter.
diff --git a/src/adapters/MathsatExpressionAdapter.h b/src/adapters/MathsatExpressionAdapter.h
index db5bf9b69..77b39cc68 100644
--- a/src/adapters/MathsatExpressionAdapter.h
+++ b/src/adapters/MathsatExpressionAdapter.h
@@ -171,7 +171,7 @@ namespace storm {
                 return expression.getValue() ? msat_make_true(env) : msat_make_false(env);
 			}
 
-			virtual boost::any visit(expressions::DoubleLiteralExpression const& expression) override {
+			virtual boost::any visit(expressions::RationalLiteralExpression const& expression) override {
 				return msat_make_number(env, std::to_string(expression.getValueAsDouble()).c_str());
 			}
 
diff --git a/src/adapters/Z3ExpressionAdapter.cpp b/src/adapters/Z3ExpressionAdapter.cpp
index 60b4e8e1c..6f4efc178 100644
--- a/src/adapters/Z3ExpressionAdapter.cpp
+++ b/src/adapters/Z3ExpressionAdapter.cpp
@@ -208,7 +208,7 @@ namespace storm {
                 return context.bool_val(expression.getValue());
             }
             
-            boost::any Z3ExpressionAdapter::visit(storm::expressions::DoubleLiteralExpression const& expression)  {
+            boost::any Z3ExpressionAdapter::visit(storm::expressions::RationalLiteralExpression const& expression)  {
                 std::stringstream fractionStream;
                 fractionStream << expression.getValue();
                 return context.real_val(fractionStream.str().c_str());
diff --git a/src/adapters/Z3ExpressionAdapter.h b/src/adapters/Z3ExpressionAdapter.h
index 4fc60c8a5..2735f5713 100644
--- a/src/adapters/Z3ExpressionAdapter.h
+++ b/src/adapters/Z3ExpressionAdapter.h
@@ -63,7 +63,7 @@ namespace storm {
             
             virtual boost::any visit(storm::expressions::BooleanLiteralExpression const& expression) override;
             
-            virtual boost::any visit(storm::expressions::DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(storm::expressions::RationalLiteralExpression const& expression) override;
             
             virtual boost::any visit(storm::expressions::IntegerLiteralExpression const& expression) override;
             
diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp
index d556d799a..3054f2fe0 100644
--- a/src/parser/ExpressionParser.cpp
+++ b/src/parser/ExpressionParser.cpp
@@ -61,7 +61,7 @@ namespace storm {
 			identifierExpression = identifier[qi::_val = phoenix::bind(&ExpressionParser::getIdentifierExpression, phoenix::ref(*this), qi::_1, allowBacktracking, qi::_pass)];
             identifierExpression.name("identifier expression");
             
-            literalExpression = trueFalse_[qi::_val = qi::_1] | rationalLiteral_[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, qi::_pass)];
+            literalExpression = trueFalse_[qi::_val = qi::_1] | rationalLiteral_[qi::_val = phoenix::bind(&ExpressionParser::createRationalLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)] | qi::int_[qi::_val = phoenix::bind(&ExpressionParser::createIntegerLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)];
             literalExpression.name("literal expression");
             
             atomicExpression = floorCeilExpression | prefixPowerExpression | minMaxExpression | (qi::lit("(") >> expression >> qi::lit(")")) | literalExpression | identifierExpression;
@@ -323,7 +323,7 @@ namespace storm {
             return manager->boolean(false);
         }
                 
-        storm::expressions::Expression ExpressionParser::createDoubleLiteralExpression(storm::RationalNumber const& value, bool& pass) const {
+        storm::expressions::Expression ExpressionParser::createRationalLiteralExpression(storm::RationalNumber const& 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;
diff --git a/src/parser/ExpressionParser.h b/src/parser/ExpressionParser.h
index c728e0b84..077be8db2 100644
--- a/src/parser/ExpressionParser.h
+++ b/src/parser/ExpressionParser.h
@@ -260,7 +260,7 @@ namespace storm {
             storm::expressions::Expression createMultExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const;
             storm::expressions::Expression createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const;
             storm::expressions::Expression createUnaryExpression(boost::optional<storm::expressions::OperatorType> const& operatorType, storm::expressions::Expression const& e1, bool& pass) const;
-            storm::expressions::Expression createDoubleLiteralExpression(storm::RationalNumber const& value, bool& pass) const;
+            storm::expressions::Expression createRationalLiteralExpression(storm::RationalNumber const& value, bool& pass) const;
             storm::expressions::Expression createIntegerLiteralExpression(int value, bool& pass) const;
             storm::expressions::Expression createMinimumMaximumExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const;
             storm::expressions::Expression createFloorCeilExpression(storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e1, bool& pass) const;
diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
index 95a326de1..7c4367952 100644
--- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp
@@ -3,7 +3,7 @@
 
 #include "src/storage/expressions/BinaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/IntegerLiteralExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/RationalLiteralExpression.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 #include "src/utility/macros.h"
 #include "src/exceptions/InvalidTypeException.h"
@@ -102,7 +102,7 @@ namespace storm {
                         case OperatorType::Power: newValue = static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break;
                         case OperatorType::Divide: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Unable to simplify division."); break;
                     }
-                    return std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(this->getManager(), newValue));
+                    return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), newValue));
                 }
             }
             
diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/DoubleLiteralExpression.cpp
index 86a2ba889..3fa226a8a 100644
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ b/src/storage/expressions/DoubleLiteralExpression.cpp
@@ -1,4 +1,4 @@
-#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/RationalLiteralExpression.h"
 #include "src/storage/expressions/ExpressionManager.h"
 #include "src/storage/expressions/ExpressionVisitor.h"
 
@@ -6,47 +6,47 @@
 
 namespace storm {
     namespace expressions {
-        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, double value) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(value)) {
+        RationalLiteralExpression::RationalLiteralExpression(ExpressionManager const& manager, double value) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(value)) {
             // Intentionally left empty.
         }
         
-        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(valueAsString)) {
+        RationalLiteralExpression::RationalLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(valueAsString)) {
             // Intentionally left empty.
         }
         
-        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value) : BaseExpression(manager, manager.getRationalType()), value(value) {
+        RationalLiteralExpression::RationalLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value) : BaseExpression(manager, manager.getRationalType()), value(value) {
             // Intentionally left empty.
         }
         
-        double DoubleLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
+        double RationalLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
             return this->getValueAsDouble();
         }
         
-        bool DoubleLiteralExpression::isLiteral() const {
+        bool RationalLiteralExpression::isLiteral() const {
             return true;
         }
         
-        void DoubleLiteralExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const {
+        void RationalLiteralExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const {
             return;
 		}
         
-        std::shared_ptr<BaseExpression const> DoubleLiteralExpression::simplify() const {
+        std::shared_ptr<BaseExpression const> RationalLiteralExpression::simplify() const {
             return this->shared_from_this();
         }
         
-        boost::any DoubleLiteralExpression::accept(ExpressionVisitor& visitor) const {
+        boost::any RationalLiteralExpression::accept(ExpressionVisitor& visitor) const {
             return visitor.visit(*this);
         }
         
-        double DoubleLiteralExpression::getValueAsDouble() const {
+        double RationalLiteralExpression::getValueAsDouble() const {
             return storm::utility::convertNumber<double>(this->value);
         }
         
-        storm::RationalNumber DoubleLiteralExpression::getValue() const {
+        storm::RationalNumber RationalLiteralExpression::getValue() const {
             return this->value;
         }
         
-        void DoubleLiteralExpression::printToStream(std::ostream& stream) const {
+        void RationalLiteralExpression::printToStream(std::ostream& stream) const {
             stream << this->getValue();
         }
     }
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
index 1b6aa28b3..4eff900b2 100644
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ b/src/storage/expressions/DoubleLiteralExpression.h
@@ -1,5 +1,5 @@
-#ifndef STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
-#define STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
+#ifndef STORM_STORAGE_EXPRESSIONS_RationalLiteralExpression_H_
+#define STORM_STORAGE_EXPRESSIONS_RationalLiteralExpression_H_
 
 #include "src/storage/expressions/BaseExpression.h"
 #include "src/utility/OsDetection.h"
@@ -8,7 +8,7 @@
 
 namespace storm {
     namespace expressions {
-        class DoubleLiteralExpression : public BaseExpression {
+        class RationalLiteralExpression : public BaseExpression {
         public:
             /*!
              * Creates an double literal expression with the given value.
@@ -16,7 +16,7 @@ namespace storm {
              * @param manager The manager responsible for this expression.
              * @param value The value of the double literal.
              */
-            DoubleLiteralExpression(ExpressionManager const& manager, double value);
+            RationalLiteralExpression(ExpressionManager const& manager, double value);
 
             /*!
              * Creates an double literal expression with the value given as a string.
@@ -24,7 +24,7 @@ namespace storm {
              * @param manager The manager responsible for this expression.
              * @param value The string representation of the value of the literal.
              */
-            DoubleLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString);
+            RationalLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString);
 
             /*!
              * Creates an double literal expression with the rational value.
@@ -32,16 +32,16 @@ namespace storm {
              * @param manager The manager responsible for this expression.
              * @param value The rational number that is the value of this literal expression.
              */
-            DoubleLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value);
+            RationalLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value);
 
             // Instantiate constructors and assignments with their default implementations.
-            DoubleLiteralExpression(DoubleLiteralExpression const& other) = default;
-            DoubleLiteralExpression& operator=(DoubleLiteralExpression const& other) = delete;
+            RationalLiteralExpression(RationalLiteralExpression const& other) = default;
+            RationalLiteralExpression& operator=(RationalLiteralExpression const& other) = delete;
 #ifndef WINDOWS
-            DoubleLiteralExpression(DoubleLiteralExpression&&) = default;
-            DoubleLiteralExpression& operator=(DoubleLiteralExpression&&) = delete;
+            RationalLiteralExpression(RationalLiteralExpression&&) = default;
+            RationalLiteralExpression& operator=(RationalLiteralExpression&&) = delete;
 #endif
-            virtual ~DoubleLiteralExpression() = default;
+            virtual ~RationalLiteralExpression() = default;
             
             // Override base class methods.
             virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
@@ -75,4 +75,4 @@ namespace storm {
     }
 }
 
-#endif /* STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_ */
\ No newline at end of file
+#endif /* STORM_STORAGE_EXPRESSIONS_RationalLiteralExpression_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionManager.cpp b/src/storage/expressions/ExpressionManager.cpp
index a92d908f3..ed51f76ee 100644
--- a/src/storage/expressions/ExpressionManager.cpp
+++ b/src/storage/expressions/ExpressionManager.cpp
@@ -65,11 +65,11 @@ namespace storm {
         }
 
         Expression ExpressionManager::rational(double value) const {
-            return Expression(std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(*this, value)));
+            return Expression(std::shared_ptr<BaseExpression>(new RationalLiteralExpression(*this, value)));
         }
         
         Expression ExpressionManager::rational(storm::RationalNumber const& value) const {
-            return Expression(std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(*this, value)));
+            return Expression(std::shared_ptr<BaseExpression>(new RationalLiteralExpression(*this, value)));
         }
         
         bool ExpressionManager::operator==(ExpressionManager const& other) const {
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
index 5fdb486c2..1abafc2a6 100644
--- a/src/storage/expressions/ExpressionVisitor.h
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -15,7 +15,7 @@ namespace storm {
         class UnaryNumericalFunctionExpression;
         class BooleanLiteralExpression;
         class IntegerLiteralExpression;
-        class DoubleLiteralExpression;
+        class RationalLiteralExpression;
         
         class ExpressionVisitor {
         public:
@@ -28,7 +28,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) = 0;
             virtual boost::any visit(BooleanLiteralExpression const& expression) = 0;
             virtual boost::any visit(IntegerLiteralExpression const& expression) = 0;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) = 0;
+            virtual boost::any visit(RationalLiteralExpression const& expression) = 0;
         };
     }
 }
diff --git a/src/storage/expressions/Expressions.h b/src/storage/expressions/Expressions.h
index d670c29e3..655cc4aab 100644
--- a/src/storage/expressions/Expressions.h
+++ b/src/storage/expressions/Expressions.h
@@ -4,7 +4,7 @@
 #include "src/storage/expressions/BinaryRelationExpression.h"
 #include "src/storage/expressions/BooleanLiteralExpression.h"
 #include "src/storage/expressions/IntegerLiteralExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/RationalLiteralExpression.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/LinearCoefficientVisitor.cpp b/src/storage/expressions/LinearCoefficientVisitor.cpp
index 3d881c25e..dc9a909f9 100644
--- a/src/storage/expressions/LinearCoefficientVisitor.cpp
+++ b/src/storage/expressions/LinearCoefficientVisitor.cpp
@@ -151,7 +151,7 @@ namespace storm {
             return VariableCoefficients(static_cast<double>(expression.getValue()));
         }
         
-        boost::any LinearCoefficientVisitor::visit(DoubleLiteralExpression const& expression) {
+        boost::any LinearCoefficientVisitor::visit(RationalLiteralExpression const& expression) {
             return VariableCoefficients(expression.getValueAsDouble());
         }
     }
diff --git a/src/storage/expressions/LinearCoefficientVisitor.h b/src/storage/expressions/LinearCoefficientVisitor.h
index b48c53d09..dea1bfc2e 100644
--- a/src/storage/expressions/LinearCoefficientVisitor.h
+++ b/src/storage/expressions/LinearCoefficientVisitor.h
@@ -75,7 +75,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(RationalLiteralExpression const& expression) override;
         };
     }
 }
diff --git a/src/storage/expressions/LinearityCheckVisitor.cpp b/src/storage/expressions/LinearityCheckVisitor.cpp
index 35e1e5c76..7a33a501a 100644
--- a/src/storage/expressions/LinearityCheckVisitor.cpp
+++ b/src/storage/expressions/LinearityCheckVisitor.cpp
@@ -85,7 +85,7 @@ namespace storm {
             return LinearityStatus::LinearWithoutVariables;
         }
         
-        boost::any LinearityCheckVisitor::visit(DoubleLiteralExpression const& expression) {
+        boost::any LinearityCheckVisitor::visit(RationalLiteralExpression const& expression) {
             return LinearityStatus::LinearWithoutVariables;
         }
     }
diff --git a/src/storage/expressions/LinearityCheckVisitor.h b/src/storage/expressions/LinearityCheckVisitor.h
index 2df8f8084..6bb35b7e8 100644
--- a/src/storage/expressions/LinearityCheckVisitor.h
+++ b/src/storage/expressions/LinearityCheckVisitor.h
@@ -29,7 +29,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(RationalLiteralExpression const& expression) override;
             
         private:
             enum class LinearityStatus { NonLinear, LinearContainsVariables, LinearWithoutVariables };
diff --git a/src/storage/expressions/SubstitutionVisitor.cpp b/src/storage/expressions/SubstitutionVisitor.cpp
index c736de156..1490e6f59 100644
--- a/src/storage/expressions/SubstitutionVisitor.cpp
+++ b/src/storage/expressions/SubstitutionVisitor.cpp
@@ -116,7 +116,7 @@ namespace storm {
         }
         
 		template<typename MapType>
-        boost::any SubstitutionVisitor<MapType>::visit(DoubleLiteralExpression const& expression) {
+        boost::any SubstitutionVisitor<MapType>::visit(RationalLiteralExpression const& expression) {
             return expression.getSharedPointer();
         }
         
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
index 343521335..5f1a93cb2 100644
--- a/src/storage/expressions/SubstitutionVisitor.h
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -37,7 +37,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(RationalLiteralExpression const& expression) override;
             
         private:
             // A mapping of variables to expressions with which they shall be replaced.
diff --git a/src/storage/expressions/ToExprtkStringVisitor.cpp b/src/storage/expressions/ToExprtkStringVisitor.cpp
index 51d9c1f34..1492aeae5 100644
--- a/src/storage/expressions/ToExprtkStringVisitor.cpp
+++ b/src/storage/expressions/ToExprtkStringVisitor.cpp
@@ -212,7 +212,7 @@ namespace storm {
             return boost::any();
         }
         
-        boost::any ToExprtkStringVisitor::visit(DoubleLiteralExpression const& expression) {
+        boost::any ToExprtkStringVisitor::visit(RationalLiteralExpression const& expression) {
             stream << expression.getValue();
             return boost::any();
         }
diff --git a/src/storage/expressions/ToExprtkStringVisitor.h b/src/storage/expressions/ToExprtkStringVisitor.h
index 6c285ff28..d68da589d 100644
--- a/src/storage/expressions/ToExprtkStringVisitor.h
+++ b/src/storage/expressions/ToExprtkStringVisitor.h
@@ -25,7 +25,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(RationalLiteralExpression const& expression) override;
             
         private:
             std::stringstream stream;
diff --git a/src/storage/expressions/ToRationalFunctionVisitor.cpp b/src/storage/expressions/ToRationalFunctionVisitor.cpp
index 533fa1f1f..60fecc08c 100644
--- a/src/storage/expressions/ToRationalFunctionVisitor.cpp
+++ b/src/storage/expressions/ToRationalFunctionVisitor.cpp
@@ -93,7 +93,7 @@ namespace storm {
         }
         
         template<typename RationalFunctionType>
-        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(DoubleLiteralExpression const& expression) {
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(RationalLiteralExpression const& expression) {
             return storm::utility::convertNumber<storm::RationalFunction>(expression.getValue());
         }
 
diff --git a/src/storage/expressions/ToRationalFunctionVisitor.h b/src/storage/expressions/ToRationalFunctionVisitor.h
index 12603f44e..1cda5028f 100644
--- a/src/storage/expressions/ToRationalFunctionVisitor.h
+++ b/src/storage/expressions/ToRationalFunctionVisitor.h
@@ -27,7 +27,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(RationalLiteralExpression const& expression) override;
             
         private:
             template<typename TP = typename RationalFunctionType::PolyType, carl::EnableIf<carl::needs_cache<TP>> = carl::dummy>
diff --git a/src/storage/expressions/ToRationalNumberVisitor.cpp b/src/storage/expressions/ToRationalNumberVisitor.cpp
index 44194cb4b..1b7319927 100644
--- a/src/storage/expressions/ToRationalNumberVisitor.cpp
+++ b/src/storage/expressions/ToRationalNumberVisitor.cpp
@@ -97,7 +97,7 @@ namespace storm {
         }
         
         template<typename RationalNumberType>
-        boost::any ToRationalNumberVisitor<RationalNumberType>::visit(DoubleLiteralExpression const& expression) {
+        boost::any ToRationalNumberVisitor<RationalNumberType>::visit(RationalLiteralExpression const& expression) {
 #ifdef STORM_HAVE_CARL
             return expression.getValue();
 #else
diff --git a/src/storage/expressions/ToRationalNumberVisitor.h b/src/storage/expressions/ToRationalNumberVisitor.h
index 2254931f6..3d53b8a87 100644
--- a/src/storage/expressions/ToRationalNumberVisitor.h
+++ b/src/storage/expressions/ToRationalNumberVisitor.h
@@ -25,7 +25,7 @@ namespace storm {
             virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override;
             virtual boost::any visit(BooleanLiteralExpression const& expression) override;
             virtual boost::any visit(IntegerLiteralExpression const& expression) override;
-            virtual boost::any visit(DoubleLiteralExpression const& expression) override;
+            virtual boost::any visit(RationalLiteralExpression const& expression) override;
         };
     }
 }
diff --git a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
index fa7cad7e3..f5178fb6f 100644
--- a/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
+++ b/src/storage/expressions/UnaryNumericalFunctionExpression.cpp
@@ -4,7 +4,7 @@
 
 #include "src/storage/expressions/UnaryNumericalFunctionExpression.h"
 #include "src/storage/expressions/IntegerLiteralExpression.h"
-#include "src/storage/expressions/DoubleLiteralExpression.h"
+#include "src/storage/expressions/RationalLiteralExpression.h"
 #include "ExpressionVisitor.h"
 #include "src/utility/macros.h"
 #include "src/exceptions/InvalidTypeException.h"
@@ -87,7 +87,7 @@ namespace storm {
                         case OperatorType::Floor: value = std::floor(boost::get<double>(operandEvaluation)); break;
                         case OperatorType::Ceil: value = std::ceil(boost::get<double>(operandEvaluation)); break;
                     }
-                    return std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(this->getManager(), value));
+                    return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), value));
                 }
             }
             

From 984abfd22bfc0df35d90d3c933f282b089f0fd20 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 15 Aug 2016 16:56:26 +0200
Subject: [PATCH 06/20] proper renaming of files

Former-commit-id: 5594ddec3849939f24194f7d3d6c8648b3e70ee8
---
 ...{DoubleLiteralExpression.cpp => RationalLiteralExpression.cpp} | 0
 .../{DoubleLiteralExpression.h => RationalLiteralExpression.h}    | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename src/storage/expressions/{DoubleLiteralExpression.cpp => RationalLiteralExpression.cpp} (100%)
 rename src/storage/expressions/{DoubleLiteralExpression.h => RationalLiteralExpression.h} (100%)

diff --git a/src/storage/expressions/DoubleLiteralExpression.cpp b/src/storage/expressions/RationalLiteralExpression.cpp
similarity index 100%
rename from src/storage/expressions/DoubleLiteralExpression.cpp
rename to src/storage/expressions/RationalLiteralExpression.cpp
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/RationalLiteralExpression.h
similarity index 100%
rename from src/storage/expressions/DoubleLiteralExpression.h
rename to src/storage/expressions/RationalLiteralExpression.h

From f342ce3287f8b2aacb6fd9149fe24a548b1a2ca3 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 15 Aug 2016 20:29:50 +0200
Subject: [PATCH 07/20] translation from expressions involving the power
 operator to rational functions/rational numbers is now possible

Former-commit-id: e0ce43ab35f88de46426b967c91b584e5adbe955
---
 src/storage/expressions/ToRationalFunctionVisitor.cpp |  6 ++++++
 src/utility/constants.cpp                             | 11 ++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/storage/expressions/ToRationalFunctionVisitor.cpp b/src/storage/expressions/ToRationalFunctionVisitor.cpp
index 60fecc08c..a219066e4 100644
--- a/src/storage/expressions/ToRationalFunctionVisitor.cpp
+++ b/src/storage/expressions/ToRationalFunctionVisitor.cpp
@@ -34,6 +34,7 @@ namespace storm {
         boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryNumericalFunctionExpression const& expression) {
             RationalFunctionType firstOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getFirstOperand()->accept(*this));
             RationalFunctionType secondOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getSecondOperand()->accept(*this));
+            uint_fast64_t exponentAsInteger = 0;
             switch(expression.getOperatorType()) {
                 case BinaryNumericalFunctionExpression::OperatorType::Plus:
                     return firstOperandAsRationalFunction + secondOperandAsRationalFunction;
@@ -47,6 +48,11 @@ namespace storm {
                 case BinaryNumericalFunctionExpression::OperatorType::Divide:
                     return firstOperandAsRationalFunction / secondOperandAsRationalFunction;
                     break;
+                case BinaryNumericalFunctionExpression::OperatorType::Power:
+                    STORM_LOG_THROW(storm::utility::isInteger(secondOperandAsRationalFunction), storm::exceptions::InvalidArgumentException, "Exponent of power operator must be a positive integer.");
+                    exponentAsInteger = storm::utility::convertNumber<uint_fast64_t>(secondOperandAsRationalFunction);
+                    return storm::utility::pow(firstOperandAsRationalFunction, exponentAsInteger);
+                    break;
                 default:
                     STORM_LOG_ASSERT(false, "Illegal operator type.");
             }
diff --git a/src/utility/constants.cpp b/src/utility/constants.cpp
index 2630ed285..6d954722a 100644
--- a/src/utility/constants.cpp
+++ b/src/utility/constants.cpp
@@ -115,6 +115,10 @@ namespace storm {
             return carl::isInteger(number);
         }
 
+        template<>
+        bool isInteger(storm::RationalFunction const& func) {
+            return storm::utility::isConstant(func) && storm::utility::isOne(func.denominator());
+        }
 #endif
         
         template<typename ValueType>
@@ -203,7 +207,12 @@ namespace storm {
         RationalFunction convertNumber(RationalNumber const& number) {
             return RationalFunction(number);
         }
-        
+
+        template<>
+        uint_fast64_t convertNumber(RationalFunction const& func) {
+            return carl::toInt<unsigned long>(func.nominatorAsNumber());
+        }
+
         template<>
         RationalNumber abs(storm::RationalNumber const& number) {
             return carl::abs(number);

From 49b663aa87da00c0277e3ba3be664d121b8803ba Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 15 Aug 2016 22:03:29 +0200
Subject: [PATCH 08/20] started working on python script that automatically
 packages the binary for mac os

Former-commit-id: 11a73f85e7493bc3ab940241599cdab6d505ab91
---
 util/osx-package/packager.py | 47 ++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 util/osx-package/packager.py

diff --git a/util/osx-package/packager.py b/util/osx-package/packager.py
new file mode 100644
index 000000000..39d06a667
--- /dev/null
+++ b/util/osx-package/packager.py
@@ -0,0 +1,47 @@
+import argparse
+import subprocess
+import os
+
+def get_dependencies(file):
+    # Call otool -L file to obtain the dependencies.
+    proc = subprocess.Popen(["otool", "-L", args.binary], stdout=subprocess.PIPE)
+    result = {}
+    for line_bytes in proc.stdout:
+        line = line_bytes.decode("utf-8").strip()
+        lib = line.split()[0]
+        if (lib.startswith("@")):
+            lib = lib.split("/", 1)[1]
+        (base, file) = os.path.split(lib)
+        print(base + " // " + file)
+    
+    return result
+
+def parse_arguments():
+    parser = argparse.ArgumentParser(description='Package the storm binary on Mac OS.')
+    parser.add_argument('binary', help='the binary to package')
+    args = parser.parse_args()
+    return args
+
+dep_exeptions = set()
+dep_exeptions.add("libSystem.B.dylib")
+dep_exeptions.add("libc++.1.dylib")
+
+def rec_gather_all_dependencies(file, deps = set()):
+    current_deps = get_dependencies(file)
+    new_deps = current_deps.keys() - dep_exeptions - deps
+    deps = deps | current_deps.keys()
+    
+    for d in new_deps:
+        rec_gather_all_dependencies(file, deps)
+    
+    return deps
+
+def print_deps(deps):
+    print("Found the following dependencies:")
+    for d in deps:
+        print(d)
+
+if __name__ == "__main__":
+    args = parse_arguments()
+    deps = rec_gather_all_dependencies(args.binary)
+    print_deps(deps)

From 8d88572b03a3095f8ff9d604850f5553339deae8 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 16 Aug 2016 15:50:37 +0200
Subject: [PATCH 09/20] packager and script

Former-commit-id: 4db9b3616e8549a9b1a436f62e9b9f1a14d3728c
---
 util/osx-package/packager.py | 94 ++++++++++++++++++++++++++++--------
 util/osx-package/run.sh      | 10 ++++
 2 files changed, 85 insertions(+), 19 deletions(-)
 create mode 100644 util/osx-package/run.sh

diff --git a/util/osx-package/packager.py b/util/osx-package/packager.py
index 39d06a667..60b26a8b8 100644
--- a/util/osx-package/packager.py
+++ b/util/osx-package/packager.py
@@ -1,6 +1,7 @@
 import argparse
 import subprocess
 import os
+from shutil import copyfile
 
 def get_dependencies(file):
     # Call otool -L file to obtain the dependencies.
@@ -16,32 +17,87 @@ def get_dependencies(file):
     
     return result
 
+def create_package(args):
+    create_package_dirs(args.dir)
+    copy_binary_to_package_dir(args.bin, args.binary_basename, args.dir)
+    run_dylibbundler(args.bundler_binary, args.dir, args.binary_basename)
+    pass
+
 def parse_arguments():
     parser = argparse.ArgumentParser(description='Package the storm binary on Mac OS.')
-    parser.add_argument('binary', help='the binary to package')
+    parser.add_argument('--bin', dest='bin', help='the binary to package', default='storm')
+    parser.add_argument('--dir', dest='dir', help='the root directory of the package (will be created if it does not exist)', default='.')
+    parser.add_argument('--dylibbundler', dest='bundler_binary', help='the binary of the dylibbundler', default='dylibbundler')
     args = parser.parse_args()
+    args.binary_dir = os.path.split(args.bin)[0]
+    args.binary_basename = os.path.split(args.bin)[1]
     return args
 
-dep_exeptions = set()
-dep_exeptions.add("libSystem.B.dylib")
-dep_exeptions.add("libc++.1.dylib")
+def create_package_dirs(root_dir):
+    if not os.path.exists(root_dir):
+        os.makedirs(root_dir)
+    if not os.path.exists(root_dir + "/bin"):
+        os.makedirs(root_dir + "/bin")
+    if not os.path.exists(root_dir + "/lib"):
+        os.makedirs(root_dir + "/bin")
+    pass
 
-def rec_gather_all_dependencies(file, deps = set()):
-    current_deps = get_dependencies(file)
-    new_deps = current_deps.keys() - dep_exeptions - deps
-    deps = deps | current_deps.keys()
-    
-    for d in new_deps:
-        rec_gather_all_dependencies(file, deps)
-    
-    return deps
+def copy_binary_to_package_dir(binary, binary_basename, root_dir):
+    copyfile(binary, root_dir + "/bin/storm")
+    pass
+
+def run_dylibbundler(bundler_binary, root_dir, binary_basename):
+    command = [bundler_binary, "-cd", "-od", "-b", "-p", "@executable_path/../lib", "-x", root_dir + "/bin/" + binary_basename, "-d", root_dir + "/lib"]
+    print("executing " + str(command))
+    #proc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+    pass
+
+def fix_paths(root_dir, binary_basename):
+    fix_paths_file(root_dir + "/bin/" + binary_basename)
+    for file in os.listdir(root_dir + "/lib"):
+        fix_paths_file(root_dir + "/lib/" + file)
+        pass
+    pass
+
+def fix_paths_file(file):
+    print("fixing paths for " + file)
+    fixable_deps = get_fixable_deps(file)
+    for (path, lib) in fixable_deps:
+        change_fixable_dep(file, path, lib)
+
+native_libs = ["libc++.1.dylib", "libSystem.B.dylib"]
+
+def get_fixable_deps(file):
+    # Call otool -L file to obtain the dependencies.
+    proc = subprocess.Popen(["otool", "-L", file], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+    result = []
+    for line_bytes in proc.stdout:
+        line = line_bytes.decode("utf-8").strip()
+        lib = line.split()[0]
+        if lib.startswith("@rpath/"):
+            result.append(("@rpath", lib.split("/", 1)[1]))
+        elif lib.startswith("/"):
+            path_file = os.path.split(lib)
+            if path_file[1] not in native_libs:
+                result.append((path_file[0], path_file[1]))
+    return result
 
-def print_deps(deps):
-    print("Found the following dependencies:")
-    for d in deps:
-        print(d)
+def change_fixable_dep(file, path, lib):
+    # Call install_name_tool to change the fixable dependencies
+    command = ["install_name_tool", "-change", path + "/" + lib, "@executable_path/../lib/" + lib, file]
+    print("executing " + str(command))
+    proc = subprocess.Popen(command, stdout=subprocess.PIPE)
+    #print ("after call to install_name_tool")
+    #proc = subprocess.Popen(["otool", "-L", file], stdout=subprocess.PIPE)
+    #for line_bytes in proc.stdout:
+    #    line = line_bytes.decode("utf-8").strip()
+    #    print(line)
+    pass
 
 if __name__ == "__main__":
     args = parse_arguments()
-    deps = rec_gather_all_dependencies(args.binary)
-    print_deps(deps)
+
+    #create_package(args)
+    fix_paths(args.dir, args.binary_basename)
+
+    
diff --git a/util/osx-package/run.sh b/util/osx-package/run.sh
new file mode 100644
index 000000000..0db5b2b5d
--- /dev/null
+++ b/util/osx-package/run.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+DYLIBBUNDLER_DIR=/Users/chris/work/macdylibbundler/
+
+mkdir -p $1
+mkdir -p $1/bin
+mkdir -p $1/lib
+cp $2 $1/bin
+$DYLIBBUNDLER_DIR/dylibbundler -cd -od -b -p @executable_path/../lib -x $1/bin/storm -d $1/lib
+python packager.py --bin storm --dir $1

From 07a457b5d1beded6946652ed83dc900183d94120 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 17 Aug 2016 11:33:14 +0200
Subject: [PATCH 10/20] renaming packaging script

Former-commit-id: ef506391b4d4211df4c021ac720e8c9da9fd43d2
---
 util/osx-package/{run.sh => package.sh} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename util/osx-package/{run.sh => package.sh} (100%)

diff --git a/util/osx-package/run.sh b/util/osx-package/package.sh
similarity index 100%
rename from util/osx-package/run.sh
rename to util/osx-package/package.sh

From 5109c45c23af58398e7751db8639b039f62082c3 Mon Sep 17 00:00:00 2001
From: Mavo <matthias.volk@rwth-aachen.de>
Date: Fri, 19 Aug 2016 12:09:48 +0200
Subject: [PATCH 11/20] Fixed returning result for pCTMC

Former-commit-id: 2db7f87f65cefd4da1250163fe73af85a8f9c806
---
 src/utility/storm.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/utility/storm.h b/src/utility/storm.h
index ad9cb1de0..4a32c7ad4 100644
--- a/src/utility/storm.h
+++ b/src/utility/storm.h
@@ -381,10 +381,10 @@ namespace storm {
         if (model->getType() == storm::models::ModelType::Dtmc) {
             result = verifySparseDtmc(model->template as<storm::models::sparse::Dtmc<storm::RationalFunction>>(), task);
         } else if (model->getType() == storm::models::ModelType::Mdp) {
-            std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> mdp = model->template as<storm::models::sparse::Mdp<storm::RationalFunction>>();
+            //std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> mdp = model->template as<storm::models::sparse::Mdp<storm::RationalFunction>>();
             STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The parametric engine currently does not support MDPs.");
         } else if (model->getType() == storm::models::ModelType::Ctmc) {
-            verifySparseCtmc(model->template as<storm::models::sparse::Ctmc<storm::RationalFunction>>(), task);
+            result = verifySparseCtmc(model->template as<storm::models::sparse::Ctmc<storm::RationalFunction>>(), task);
         } else {
             STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The parametric engine currently does not support " << model->getType());
         }

From 6d5f4dc9c924985e7e0879a480750c1b8e4f70a9 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Aug 2016 08:56:59 +0200
Subject: [PATCH 12/20] fixed bug in detection whether parameters are only used
 in probabilities/rewards

Former-commit-id: 1929f5e079a03863d9b838043070be4ffe640314
---
 src/storage/prism/Constant.cpp | 7 ++++++-
 src/storage/prism/Module.cpp   | 4 +++-
 src/storage/prism/Program.cpp  | 6 ++++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/storage/prism/Constant.cpp b/src/storage/prism/Constant.cpp
index 0416dc4b9..1c3b07057 100644
--- a/src/storage/prism/Constant.cpp
+++ b/src/storage/prism/Constant.cpp
@@ -42,7 +42,12 @@ namespace storm {
         }
         
         std::ostream& operator<<(std::ostream& stream, Constant const& constant) {
-            stream << "const " << constant.getExpressionVariable().getType() << " ";
+            stream << "const ";
+            if (constant.getType().isRationalType()) {
+                stream << "double" << " ";
+            } else {
+                stream << constant.getType() << " ";
+            }
             stream << constant.getName();
             if (constant.isDefined()) {
                 stream << " = " << constant.getExpression();
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index d4168196d..7b929edfc 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -216,7 +216,9 @@ namespace storm {
             }
             
             for (auto const& command : this->getCommands()) {
-                command.containsVariablesOnlyInUpdateProbabilities(undefinedConstantVariables);
+                if (!command.containsVariablesOnlyInUpdateProbabilities(undefinedConstantVariables)) {
+                    return false;
+                }
             }
             
             return true;
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index c1a1e4cf0..4962157eb 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -230,7 +230,7 @@ namespace storm {
             // constants' variables is empty (except for the update probabilities).
             
             // Start by checking the defining expressions of all defined constants. If it contains a currently undefined
-            //constant, we need to mark the target constant as undefined as well.
+            // constant, we need to mark the target constant as undefined as well.
             for (auto const& constant : this->getConstants()) {
                 if (constant.isDefined()) {
                     if (constant.getExpression().containsVariable(undefinedConstantVariables)) {
@@ -266,7 +266,9 @@ namespace storm {
             
             // Proceed by checking each of the modules.
             for (auto const& module : this->getModules()) {
-                module.containsVariablesOnlyInUpdateProbabilities(undefinedConstantVariables);
+                if (!module.containsVariablesOnlyInUpdateProbabilities(undefinedConstantVariables)) {
+                    return false;
+                }
             }
             
             // Check the reward models.

From e6d9c85749964659472384a2fe5d40ddaf26de01 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Aug 2016 19:33:40 +0200
Subject: [PATCH 13/20] fixed some bugs related to simplifaction of PRISM
 programs

Former-commit-id: 3c81bcac8d34b9a88180a0542c7b1e1f305848b3
---
 src/generator/JaniNextStateGenerator.cpp  |  3 +
 src/generator/PrismNextStateGenerator.cpp |  9 ++-
 src/parser/PrismParser.cpp                |  2 +
 src/storage/prism/Module.h                |  1 -
 src/storage/prism/Program.cpp             | 72 ++++++++++++++++++-----
 src/storage/prism/RewardModel.cpp         | 18 ++++++
 src/storage/prism/RewardModel.h           |  9 +++
 src/utility/storm.cpp                     |  2 +-
 8 files changed, 95 insertions(+), 21 deletions(-)

diff --git a/src/generator/JaniNextStateGenerator.cpp b/src/generator/JaniNextStateGenerator.cpp
index cfb08fb79..0b2fad41a 100644
--- a/src/generator/JaniNextStateGenerator.cpp
+++ b/src/generator/JaniNextStateGenerator.cpp
@@ -161,6 +161,9 @@ namespace storm {
                 }
                 
                 // Block the current initial state to search for the next one.
+                if (!blockingExpression.isInitialized()) {
+                    break;
+                }
                 solver->add(blockingExpression);
             }
             
diff --git a/src/generator/PrismNextStateGenerator.cpp b/src/generator/PrismNextStateGenerator.cpp
index c0026a98d..7eb2291c5 100644
--- a/src/generator/PrismNextStateGenerator.cpp
+++ b/src/generator/PrismNextStateGenerator.cpp
@@ -23,8 +23,9 @@ namespace storm {
         
         template<typename ValueType, typename StateType>
         PrismNextStateGenerator<ValueType, StateType>::PrismNextStateGenerator(storm::prism::Program const& program, NextStateGeneratorOptions const& options, bool flag) : NextStateGenerator<ValueType, StateType>(program.getManager(), options), program(program), rewardModels() {
+            STORM_LOG_TRACE("Creating next-state generator for PRISM program: " << program);
             STORM_LOG_THROW(!this->program.specifiesSystemComposition(), storm::exceptions::WrongFormatException, "The explicit next-state generator currently does not support custom system compositions.");
-            
+                        
             // Only after checking validity of the program, we initialize the variable information.
             this->checkValid(program);
             this->variableInformation = VariableInformation(program);
@@ -166,6 +167,9 @@ namespace storm {
                 initialStateIndices.push_back(id);
                 
                 // Block the current initial state to search for the next one.
+                if (!blockingExpression.isInitialized()) {
+                    break;
+                }
                 solver->add(blockingExpression);
             }
             
@@ -314,7 +318,7 @@ namespace storm {
         template<typename ValueType, typename StateType>
         boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> PrismNextStateGenerator<ValueType, StateType>::getActiveCommandsByActionIndex(uint_fast64_t const& actionIndex) {
             boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> result((std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>()));
-            
+                        
             // Iterate over all modules.
             for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
                 storm::prism::Module const& module = program.getModule(i);
@@ -445,7 +449,6 @@ namespace storm {
                         
                         for (uint_fast64_t i = 0; i < iteratorList.size(); ++i) {
                             storm::prism::Command const& command = *iteratorList[i];
-                            
                             for (uint_fast64_t j = 0; j < command.getNumberOfUpdates(); ++j) {
                                 storm::prism::Update const& update = command.getUpdate(j);
                                 
diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 7d54f18c6..f9f4350b9 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -65,6 +65,8 @@ namespace storm {
                 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << ".");
             }
             
+            STORM_LOG_TRACE("Parsed PRISM input: " << result);
+            
             return result;
         }
         
diff --git a/src/storage/prism/Module.h b/src/storage/prism/Module.h
index 620432580..df8a61c21 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -104,7 +104,6 @@ namespace storm {
              */
             std::set<storm::expressions::Variable> getAllExpressionVariables() const;
             
-            
             /*!
              * Retrieves a list of expressions that characterize the legal ranges of all variables declared by this
              * module.
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index 4962157eb..acb17a17e 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -734,6 +734,12 @@ namespace storm {
                 }
             }
             
+            // As we possibly delete some commands and some actions might be dropped from modules altogether, we need to
+            // maintain a list of actions that we need to remove in other modules. For example, if module A loses all [a]
+            // commands, we need to delete all [a] commands from all other modules as well. If we do not do that, we will
+            // remove the forced synchronization that was there before.
+            std::set<uint_fast64_t> actionIndicesToDelete;
+            
             // Now we can substitute the constants in all expressions appearing in the program.
             std::vector<BooleanVariable> newBooleanVariables;
             newBooleanVariables.reserve(this->getNumberOfGlobalBooleanVariables());
@@ -757,6 +763,9 @@ namespace storm {
             newModules.reserve(this->getNumberOfModules());
             for (auto const& module : this->getModules()) {
                 newModules.emplace_back(module.substitute(constantSubstitution));
+                
+                // Determine the set of action indices that have been deleted entirely.
+                std::set_difference(module.getSynchronizingActionIndices().begin(), module.getSynchronizingActionIndices().end(), newModules.back().getSynchronizingActionIndices().begin(), newModules.back().getSynchronizingActionIndices().end(), std::inserter(actionIndicesToDelete, actionIndicesToDelete.begin()));
             }
             
             std::vector<RewardModel> newRewardModels;
@@ -773,7 +782,37 @@ namespace storm {
                 newLabels.emplace_back(label.substitute(constantSubstitution));
             }
             
-            return Program(this->manager, this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, this->getActionNameToIndexMapping(), newRewardModels, newLabels, newInitialConstruct, this->getOptionalSystemCompositionConstruct());
+            // If we have to delete whole actions, do so now.
+            std::map<std::string, uint_fast64_t> newActionToIndexMap;
+            if (!actionIndicesToDelete.empty()) {
+                boost::container::flat_set<uint_fast64_t> actionsToKeep;
+                std::set_difference(this->getSynchronizingActionIndices().begin(), this->getSynchronizingActionIndices().end(), actionIndicesToDelete.begin(), actionIndicesToDelete.end(), std::inserter(actionsToKeep, actionsToKeep.begin()));
+                
+                // Insert the silent action as this is not contained in the synchronizing action indices.
+                actionsToKeep.insert(0);
+                
+                std::vector<Module> cleanedModules;
+                cleanedModules.reserve(this->getNumberOfModules());
+                for (auto const& module : newModules) {
+                    cleanedModules.emplace_back(module.restrictCommands(actionsToKeep));
+                }
+                newModules = std::move(cleanedModules);
+                
+                std::vector<RewardModel> cleanedRewardModels;
+                cleanedRewardModels.reserve(this->getNumberOfRewardModels());
+                for (auto const& rewardModel : newRewardModels) {
+                    cleanedRewardModels.emplace_back(rewardModel.restrictActionRelatedRewards(actionsToKeep));
+                }
+                newRewardModels = std::move(cleanedRewardModels);
+                
+                for (auto const& entry : this->getActionNameToIndexMapping()) {
+                    if (actionsToKeep.find(entry.second) != actionsToKeep.end()) {
+                        newActionToIndexMap.emplace(entry.first, entry.second);
+                    }
+                }
+            }
+            
+            return Program(this->manager, this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, actionIndicesToDelete.empty() ? this->getActionNameToIndexMapping() : newActionToIndexMap, newRewardModels, newLabels, newInitialConstruct, this->getOptionalSystemCompositionConstruct());
         }
         
         void Program::checkValidity(Program::ValidityCheckLevel lvl) const {
@@ -1153,17 +1192,19 @@ namespace storm {
         }
         
         Program Program::simplify() {
+            // Start by substituting the constants, because this will potentially erase some commands or even actions.
+            Program substitutedProgram = this->substituteConstants();
+            
             std::vector<Module> newModules;
-            std::vector<Constant> newConstants = this->getConstants();
-            for (auto const& module : this->getModules()) {
-                // Remove identity assignments from the updates
+            std::vector<Constant> newConstants = substitutedProgram.getConstants();
+            for (auto const& module : substitutedProgram.getModules()) {
+                // Remove identity assignments from the updates.
                 std::vector<Command> newCommands;
                 for (auto const& command : module.getCommands()) {
                     newCommands.emplace_back(command.removeIdentityAssignmentsFromUpdates());
                 }
                 
-                // Substitute Variables by Global constants if possible.
-                
+                // Substitute variables by global constants if possible.
                 std::map<storm::expressions::Variable, storm::expressions::Expression> booleanVars;
                 std::map<storm::expressions::Variable, storm::expressions::Expression> integerVars;
                 for (auto const& variable : module.getBooleanVariables()) {
@@ -1179,11 +1220,11 @@ namespace storm {
                         // Check all assignments.
                         for (auto const& assignment : update.getAssignments()) {
                             auto bit = booleanVars.find(assignment.getVariable());
-                            if(bit != booleanVars.end()) {
+                            if (bit != booleanVars.end()) {
                                 booleanVars.erase(bit);
                             } else {
                                 auto iit = integerVars.find(assignment.getVariable());
-                                if(iit != integerVars.end()) {
+                                if (iit != integerVars.end()) {
                                     integerVars.erase(iit);
                                 }
                             }
@@ -1192,31 +1233,30 @@ namespace storm {
                 }
                 
                 std::vector<storm::prism::BooleanVariable> newBVars;
-                for(auto const& variable : module.getBooleanVariables()) {
-                    if(booleanVars.count(variable.getExpressionVariable()) == 0) {
+                for (auto const& variable : module.getBooleanVariables()) {
+                    if (booleanVars.find(variable.getExpressionVariable()) == booleanVars.end()) {
                         newBVars.push_back(variable);
                     }
                 }
                 std::vector<storm::prism::IntegerVariable> newIVars;
-                for(auto const& variable : module.getIntegerVariables()) {
-                    if(integerVars.count(variable.getExpressionVariable()) == 0) {
+                for (auto const& variable : module.getIntegerVariables()) {
+                    if (integerVars.find(variable.getExpressionVariable()) == integerVars.end()) {
                         newIVars.push_back(variable);
                     }
                 }
                 
                 newModules.emplace_back(module.getName(), newBVars, newIVars, newCommands);
                 
-                for(auto const& entry : booleanVars) {
+                for (auto const& entry : booleanVars) {
                     newConstants.emplace_back(entry.first, entry.second);
                 }
                 
-                for(auto const& entry : integerVars) {
+                for (auto const& entry : integerVars) {
                     newConstants.emplace_back(entry.first, entry.second);
                 }
             }
             
-            return replaceModulesAndConstantsInProgram(newModules, newConstants).substituteConstants();
-            
+            return substitutedProgram.replaceModulesAndConstantsInProgram(newModules, newConstants);
         }
         
         Program Program::replaceModulesAndConstantsInProgram(std::vector<Module> const& newModules, std::vector<Constant> const& newConstants) {
diff --git a/src/storage/prism/RewardModel.cpp b/src/storage/prism/RewardModel.cpp
index 30c43728c..52ef5dc67 100644
--- a/src/storage/prism/RewardModel.cpp
+++ b/src/storage/prism/RewardModel.cpp
@@ -81,6 +81,24 @@ namespace storm {
             return true;
         }
         
+        RewardModel RewardModel::restrictActionRelatedRewards(boost::container::flat_set<uint_fast64_t> const& actionIndicesToKeep) const {
+            std::vector<StateActionReward> newStateActionRewards;
+            for (auto const& stateActionReward : this->getStateActionRewards()) {
+                if (actionIndicesToKeep.find(stateActionReward.getActionIndex()) != actionIndicesToKeep.end()) {
+                    newStateActionRewards.emplace_back(stateActionReward);
+                }
+            }
+
+            std::vector<TransitionReward> newTransitionRewards;
+            for (auto const& transitionReward : this->getTransitionRewards()) {
+                if (actionIndicesToKeep.find(transitionReward.getActionIndex()) != actionIndicesToKeep.end()) {
+                    newTransitionRewards.emplace_back(transitionReward);
+                }
+            }
+
+            return RewardModel(this->getName(), this->getStateRewards(), newStateActionRewards, newTransitionRewards, this->getFilename(), this->getLineNumber());
+        }
+        
         std::ostream& operator<<(std::ostream& stream, RewardModel const& rewardModel) {
             stream << "rewards";
             if (rewardModel.getName() != "") {
diff --git a/src/storage/prism/RewardModel.h b/src/storage/prism/RewardModel.h
index c62aff61a..01ab69508 100644
--- a/src/storage/prism/RewardModel.h
+++ b/src/storage/prism/RewardModel.h
@@ -4,6 +4,7 @@
 #include <string>
 #include <vector>
 #include <map>
+#include <boost/container/flat_set.hpp>
 
 #include "src/storage/prism/StateReward.h"
 #include "src/storage/prism/StateActionReward.h"
@@ -108,6 +109,14 @@ namespace storm {
              */
             bool containsVariablesOnlyInRewardValueExpressions(std::set<storm::expressions::Variable> const& undefinedConstantVariables) const;
             
+            /*!
+             * Restricts all action-related rewards of the reward model to the ones with an action index in the provided set.
+             *
+             * @param actionIndicesToKeep The set of action indices to keep.
+             * @return The resulting reward model.
+             */
+            RewardModel restrictActionRelatedRewards(boost::container::flat_set<uint_fast64_t> const& actionIndicesToKeep) const;
+            
             friend std::ostream& operator<<(std::ostream& stream, RewardModel const& rewardModel);
 
         private:
diff --git a/src/utility/storm.cpp b/src/utility/storm.cpp
index 5956e72c9..c6d2f9c65 100644
--- a/src/utility/storm.cpp
+++ b/src/utility/storm.cpp
@@ -10,7 +10,7 @@
 namespace storm {
    
      storm::prism::Program parseProgram(std::string const& path) {
-        storm::prism::Program program= storm::parser::PrismParser::parse(path).simplify().simplify();
+        storm::prism::Program program = storm::parser::PrismParser::parse(path).simplify().simplify();
         program.checkValidity();
         return program;
     }

From 3ea11188b7f0c9bb6e3784686eece7678594108d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Aug 2016 19:35:03 +0200
Subject: [PATCH 14/20] fixed an issue in the CMakeLists.txt that prevented
 carl from being properly loaded if it's not already present

Former-commit-id: 95b83d39882a6bd743d65b484fb3e5d168cb7020
---
 resources/3rdparty/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt
index 042eaea43..244e24057 100644
--- a/resources/3rdparty/CMakeLists.txt
+++ b/resources/3rdparty/CMakeLists.txt
@@ -204,7 +204,7 @@ if(USE_CARL)
                 LOG_INSTALL ON
         )
 
-        add_dependencies(resources xercesc)
+        add_dependencies(resources carl)
         include_directories(${STORM_3RDPARTY_BINARY_DIR}/carl/include)
         list(APPEND STORM_LINK_LIBRARIES ${STORM_3RDPARTY_BINARY_DIR}/carl/lib/libcarl${DYNAMIC_EXT})
         set(STORM_HAVE_CARL ON)

From bcb13a4fe1140ea6d415ba94c9fd9ca167404a2b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Aug 2016 21:36:56 +0200
Subject: [PATCH 15/20] moved deletion of commands (if guard becomes false)
 from Program::substitute to Program::simplify

Former-commit-id: ec5b4d4a579898eb36252f1e0b0fb786b8ea7c50
---
 src/storage/prism/Module.cpp  |   5 +-
 src/storage/prism/Program.cpp | 119 +++++++++++++++++-----------------
 src/storage/prism/Program.h   |   8 ---
 3 files changed, 61 insertions(+), 71 deletions(-)

diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 7b929edfc..755c4c78a 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -188,10 +188,7 @@ namespace storm {
             std::vector<Command> newCommands;
             newCommands.reserve(this->getNumberOfCommands());
             for (auto const& command : this->getCommands()) {
-                Command newCommand = command.substitute(substitution);
-                if (!newCommand.getGuardExpression().isFalse()) {
-                    newCommands.emplace_back(newCommand);
-                }
+                newCommands.emplace_back(command.substitute(substitution));
             }
             
             return Module(this->getName(), newBooleanVariables, newIntegerVariables, newCommands, this->getFilename(), this->getLineNumber());
diff --git a/src/storage/prism/Program.cpp b/src/storage/prism/Program.cpp
index acb17a17e..cdc3d323a 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -717,7 +717,7 @@ namespace storm {
         }
         
         Program Program::substituteConstants() const {
-            // We start by creating the appropriate substitution
+            // We start by creating the appropriate substitution.
             std::map<storm::expressions::Variable, storm::expressions::Expression> constantSubstitution;
             std::vector<Constant> newConstants(this->getConstants());
             for (uint_fast64_t constantIndex = 0; constantIndex < newConstants.size(); ++constantIndex) {
@@ -734,12 +734,6 @@ namespace storm {
                 }
             }
             
-            // As we possibly delete some commands and some actions might be dropped from modules altogether, we need to
-            // maintain a list of actions that we need to remove in other modules. For example, if module A loses all [a]
-            // commands, we need to delete all [a] commands from all other modules as well. If we do not do that, we will
-            // remove the forced synchronization that was there before.
-            std::set<uint_fast64_t> actionIndicesToDelete;
-            
             // Now we can substitute the constants in all expressions appearing in the program.
             std::vector<BooleanVariable> newBooleanVariables;
             newBooleanVariables.reserve(this->getNumberOfGlobalBooleanVariables());
@@ -763,9 +757,6 @@ namespace storm {
             newModules.reserve(this->getNumberOfModules());
             for (auto const& module : this->getModules()) {
                 newModules.emplace_back(module.substitute(constantSubstitution));
-                
-                // Determine the set of action indices that have been deleted entirely.
-                std::set_difference(module.getSynchronizingActionIndices().begin(), module.getSynchronizingActionIndices().end(), newModules.back().getSynchronizingActionIndices().begin(), newModules.back().getSynchronizingActionIndices().end(), std::inserter(actionIndicesToDelete, actionIndicesToDelete.begin()));
             }
             
             std::vector<RewardModel> newRewardModels;
@@ -782,37 +773,7 @@ namespace storm {
                 newLabels.emplace_back(label.substitute(constantSubstitution));
             }
             
-            // If we have to delete whole actions, do so now.
-            std::map<std::string, uint_fast64_t> newActionToIndexMap;
-            if (!actionIndicesToDelete.empty()) {
-                boost::container::flat_set<uint_fast64_t> actionsToKeep;
-                std::set_difference(this->getSynchronizingActionIndices().begin(), this->getSynchronizingActionIndices().end(), actionIndicesToDelete.begin(), actionIndicesToDelete.end(), std::inserter(actionsToKeep, actionsToKeep.begin()));
-                
-                // Insert the silent action as this is not contained in the synchronizing action indices.
-                actionsToKeep.insert(0);
-                
-                std::vector<Module> cleanedModules;
-                cleanedModules.reserve(this->getNumberOfModules());
-                for (auto const& module : newModules) {
-                    cleanedModules.emplace_back(module.restrictCommands(actionsToKeep));
-                }
-                newModules = std::move(cleanedModules);
-                
-                std::vector<RewardModel> cleanedRewardModels;
-                cleanedRewardModels.reserve(this->getNumberOfRewardModels());
-                for (auto const& rewardModel : newRewardModels) {
-                    cleanedRewardModels.emplace_back(rewardModel.restrictActionRelatedRewards(actionsToKeep));
-                }
-                newRewardModels = std::move(cleanedRewardModels);
-                
-                for (auto const& entry : this->getActionNameToIndexMapping()) {
-                    if (actionsToKeep.find(entry.second) != actionsToKeep.end()) {
-                        newActionToIndexMap.emplace(entry.first, entry.second);
-                    }
-                }
-            }
-            
-            return Program(this->manager, this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, actionIndicesToDelete.empty() ? this->getActionNameToIndexMapping() : newActionToIndexMap, newRewardModels, newLabels, newInitialConstruct, this->getOptionalSystemCompositionConstruct());
+            return Program(this->manager, this->getModelType(), newConstants, newBooleanVariables, newIntegerVariables, newFormulas, newModules, this->getActionNameToIndexMapping(), newRewardModels, newLabels, newInitialConstruct, this->getOptionalSystemCompositionConstruct());
         }
         
         void Program::checkValidity(Program::ValidityCheckLevel lvl) const {
@@ -1195,13 +1156,22 @@ namespace storm {
             // Start by substituting the constants, because this will potentially erase some commands or even actions.
             Program substitutedProgram = this->substituteConstants();
             
+            // As we possibly delete some commands and some actions might be dropped from modules altogether, we need to
+            // maintain a list of actions that we need to remove in other modules. For example, if module A loses all [a]
+            // commands, we need to delete all [a] commands from all other modules as well. If we do not do that, we will
+            // remove the forced synchronization that was there before.
+            std::set<uint_fast64_t> actionIndicesToDelete;
+            
             std::vector<Module> newModules;
             std::vector<Constant> newConstants = substitutedProgram.getConstants();
             for (auto const& module : substitutedProgram.getModules()) {
-                // Remove identity assignments from the updates.
+                
+                // Discard all commands with a guard equivalent to false and remove identity assignments from the updates.
                 std::vector<Command> newCommands;
                 for (auto const& command : module.getCommands()) {
-                    newCommands.emplace_back(command.removeIdentityAssignmentsFromUpdates());
+                    if (!command.getGuardExpression().isFalse()) {
+                        newCommands.emplace_back(command.removeIdentityAssignmentsFromUpdates());
+                    }
                 }
                 
                 // Substitute variables by global constants if possible.
@@ -1214,38 +1184,44 @@ namespace storm {
                     integerVars.emplace(variable.getExpressionVariable(), variable.getInitialValueExpression());
                 }
                 
+                // Collect all variables that are being written. These variables cannot be turned to constants.
                 for (auto const& command : newCommands) {
                     // Check all updates.
                     for (auto const& update : command.getUpdates()) {
                         // Check all assignments.
                         for (auto const& assignment : update.getAssignments()) {
-                            auto bit = booleanVars.find(assignment.getVariable());
-                            if (bit != booleanVars.end()) {
-                                booleanVars.erase(bit);
+                            if (assignment.getVariable().getType().isBooleanType()) {
+                                auto it = booleanVars.find(assignment.getVariable());
+                                if (it != booleanVars.end()) {
+                                    booleanVars.erase(it);
+                                }
                             } else {
-                                auto iit = integerVars.find(assignment.getVariable());
-                                if (iit != integerVars.end()) {
-                                    integerVars.erase(iit);
+                                auto it = integerVars.find(assignment.getVariable());
+                                if (it != integerVars.end()) {
+                                    integerVars.erase(it);
                                 }
                             }
                         }
                     }
                 }
                 
-                std::vector<storm::prism::BooleanVariable> newBVars;
+                std::vector<storm::prism::BooleanVariable> newBooleanVars;
                 for (auto const& variable : module.getBooleanVariables()) {
                     if (booleanVars.find(variable.getExpressionVariable()) == booleanVars.end()) {
-                        newBVars.push_back(variable);
+                        newBooleanVars.push_back(variable);
                     }
                 }
-                std::vector<storm::prism::IntegerVariable> newIVars;
+                std::vector<storm::prism::IntegerVariable> newIntegerVars;
                 for (auto const& variable : module.getIntegerVariables()) {
                     if (integerVars.find(variable.getExpressionVariable()) == integerVars.end()) {
-                        newIVars.push_back(variable);
+                        newIntegerVars.push_back(variable);
                     }
                 }
                 
-                newModules.emplace_back(module.getName(), newBVars, newIVars, newCommands);
+                newModules.emplace_back(module.getName(), newBooleanVars, newIntegerVars, newCommands);
+                
+                // Determine the set of action indices that have been deleted entirely.
+                std::set_difference(module.getSynchronizingActionIndices().begin(), module.getSynchronizingActionIndices().end(), newModules.back().getSynchronizingActionIndices().begin(), newModules.back().getSynchronizingActionIndices().end(), std::inserter(actionIndicesToDelete, actionIndicesToDelete.begin()));
                 
                 for (auto const& entry : booleanVars) {
                     newConstants.emplace_back(entry.first, entry.second);
@@ -1256,11 +1232,36 @@ namespace storm {
                 }
             }
             
-            return substitutedProgram.replaceModulesAndConstantsInProgram(newModules, newConstants);
-        }
-        
-        Program Program::replaceModulesAndConstantsInProgram(std::vector<Module> const& newModules, std::vector<Constant> const& newConstants) {
-            return Program(this->manager, modelType, newConstants, getGlobalBooleanVariables(), getGlobalIntegerVariables(), getFormulas(), newModules, getActionNameToIndexMapping(), getRewardModels(), getLabels(), getInitialConstruct(), this->getOptionalSystemCompositionConstruct());
+            // If we have to delete whole actions, do so now.
+            std::map<std::string, uint_fast64_t> newActionToIndexMap;
+            std::vector<RewardModel> newRewardModels;
+            if (!actionIndicesToDelete.empty()) {
+                boost::container::flat_set<uint_fast64_t> actionsToKeep;
+                std::set_difference(this->getSynchronizingActionIndices().begin(), this->getSynchronizingActionIndices().end(), actionIndicesToDelete.begin(), actionIndicesToDelete.end(), std::inserter(actionsToKeep, actionsToKeep.begin()));
+                
+                // Insert the silent action as this is not contained in the synchronizing action indices.
+                actionsToKeep.insert(0);
+                
+                std::vector<Module> cleanedModules;
+                cleanedModules.reserve(newModules.size());
+                for (auto const& module : newModules) {
+                    cleanedModules.emplace_back(module.restrictCommands(actionsToKeep));
+                }
+                newModules = std::move(cleanedModules);
+                
+                newRewardModels.reserve(substitutedProgram.getNumberOfRewardModels());
+                for (auto const& rewardModel : substitutedProgram.getRewardModels()) {
+                    newRewardModels.emplace_back(rewardModel.restrictActionRelatedRewards(actionsToKeep));
+                }
+                
+                for (auto const& entry : this->getActionNameToIndexMapping()) {
+                    if (actionsToKeep.find(entry.second) != actionsToKeep.end()) {
+                        newActionToIndexMap.emplace(entry.first, entry.second);
+                    }
+                }
+            }
+            
+            return Program(this->manager, modelType, newConstants, getGlobalBooleanVariables(), getGlobalIntegerVariables(), getFormulas(), newModules, actionIndicesToDelete.empty() ? getActionNameToIndexMapping() : newActionToIndexMap, actionIndicesToDelete.empty() ? this->getRewardModels() : newRewardModels, getLabels(), getInitialConstruct(), this->getOptionalSystemCompositionConstruct());
         }
         
         Program Program::flattenModules(std::unique_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) const {
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 71719c583..8c30079e0 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -661,14 +661,6 @@ namespace storm {
             
             // A mapping from variable names to the modules in which they were declared.
             std::map<std::string, uint_fast64_t> variableToModuleIndexMap;
-            
-            /**
-             * Takes the current program and replaces all modules. As we reuse the expression manager, we recommend to not use the original program any further.
-             * @param newModules the modules which replace the old modules.
-             * @param newConstants the constants which replace the old constants.
-             * @return A program with the new modules and constants.
-             */
-            Program replaceModulesAndConstantsInProgram(std::vector<Module> const& newModules, std::vector<Constant> const& newConstants);
         };
         
         std::ostream& operator<<(std::ostream& out, Program::ModelType const& type);

From 96891acfe7e53805c6ed6813538319704354adc7 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 22 Aug 2016 13:10:03 +0200
Subject: [PATCH 16/20] included missing (at least for some compilers) header

Former-commit-id: 4792acf519378b62e9899f5b941559c5b6fffcd6
---
 src/modelchecker/AbstractModelChecker.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index 616dcf828..5d1759b94 100644
--- a/src/modelchecker/AbstractModelChecker.cpp
+++ b/src/modelchecker/AbstractModelChecker.cpp
@@ -17,6 +17,7 @@
 #include "src/models/symbolic/Mdp.h"
 #include "src/models/sparse/MarkovAutomaton.h"
 #include "src/models/sparse/StandardRewardModel.h"
+#include "src/models/sparse/StandardRewardModel.h"
 #include "src/storage/dd/Add.h"
 #include "src/storage/dd/Bdd.h"
 

From a8383a283df2ec0de677d411ccf52d2e01a2704b Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 22 Aug 2016 13:40:20 +0200
Subject: [PATCH 17/20] fixed wrong header inclusion in previous commit

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

diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index 5d1759b94..660906acb 100644
--- a/src/modelchecker/AbstractModelChecker.cpp
+++ b/src/modelchecker/AbstractModelChecker.cpp
@@ -17,7 +17,7 @@
 #include "src/models/symbolic/Mdp.h"
 #include "src/models/sparse/MarkovAutomaton.h"
 #include "src/models/sparse/StandardRewardModel.h"
-#include "src/models/sparse/StandardRewardModel.h"
+#include "src/models/symbolic/StandardRewardModel.h"
 #include "src/storage/dd/Add.h"
 #include "src/storage/dd/Bdd.h"
 

From d1ea67524587f8cb6744d6f5c69158a5fcde7c65 Mon Sep 17 00:00:00 2001
From: TimQu <tim.quatmann@web.de>
Date: Tue, 30 Aug 2016 01:54:24 +0200
Subject: [PATCH 18/20] Added missing case for Power when converting to
 z3::expr

Former-commit-id: 4279fba636d06c93c030003b6c1f105139a6e2a8
---
 src/adapters/Z3ExpressionAdapter.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/adapters/Z3ExpressionAdapter.cpp b/src/adapters/Z3ExpressionAdapter.cpp
index 6f4efc178..a80355422 100644
--- a/src/adapters/Z3ExpressionAdapter.cpp
+++ b/src/adapters/Z3ExpressionAdapter.cpp
@@ -177,6 +177,8 @@ namespace storm {
                         return ite(leftResult <= rightResult, leftResult, rightResult);
 					case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max:
                         return ite(leftResult >= rightResult, leftResult, rightResult);
+					case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Power:
+                        return pw(leftResult,rightResult);
                     default:
                         STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical binary operator '" << static_cast<int>(expression.getOperatorType()) << "' in expression " << expression << ".");
                 }

From 1b19372a14a34fa5c828964df264fc7be1a8ebde Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 3 Sep 2016 19:20:05 +0200
Subject: [PATCH 19/20] changed a default argument initializer list to make
 compilers happier

Former-commit-id: 41dcbd2f10c6528714e4bb727c78f70f519e0400
---
 src/parser/JaniParser.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/parser/JaniParser.h b/src/parser/JaniParser.h
index e4fafcd2a..90891c759 100644
--- a/src/parser/JaniParser.h
+++ b/src/parser/JaniParser.h
@@ -34,7 +34,8 @@ namespace storm {
             storm::jani::Model parseModel();
             storm::jani::Automaton parseAutomaton(json const& automatonStructure);
             std::shared_ptr<storm::jani::Variable>  parseVariable(json const& variableStructure, std::string const& scopeDescription, bool prefWithScope = false);
-            storm::expressions::Expression parseExpression(json const& expressionStructure, std::string const& scopeDescription, std::unordered_map<std::string, std::shared_ptr<storm::jani::Variable>> const& localVars = {});
+            storm::expressions::Expression parseExpression(json const& expressionStructure, std::string const& scopeDescription, std::unordered_map<std::string, std::shared_ptr<storm::jani::Variable>> const& localVars = std::unordered_map<std::string, std::shared_ptr<storm::jani::Variable>>());
+            
         private:
             /**
              * Helper for parsing the actions of a model.
@@ -43,8 +44,6 @@ namespace storm {
 
             std::shared_ptr<storm::jani::Composition> parseComposition(json const& compositionStructure);
 
-
-
         };
     }
 }

From 92932fced10eecd82b93c5fedcfea557b2e49b2f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Mon, 5 Sep 2016 17:12:30 +0200
Subject: [PATCH 20/20] support for initial constructs in PRISM programs

Former-commit-id: 0c8132aa432a46bff8de64792bd9a9204efd2ce3
---
 src/parser/PrismParser.cpp            |  18 +--
 src/parser/PrismParser.h              |   6 +-
 src/storage/prism/BooleanVariable.cpp |  16 ++-
 src/storage/prism/BooleanVariable.h   |   2 +
 src/storage/prism/IntegerVariable.cpp |  14 ++-
 src/storage/prism/IntegerVariable.h   |   2 +
 src/storage/prism/Module.cpp          |  11 +-
 src/storage/prism/Module.h            |   5 +
 src/storage/prism/Program.cpp         | 171 ++++++++++++++++----------
 src/storage/prism/Program.h           |   7 +-
 src/storage/prism/Variable.cpp        |  12 +-
 src/storage/prism/Variable.h          |  27 ++--
 12 files changed, 199 insertions(+), 92 deletions(-)

diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index f9f4350b9..d3e5191e2 100644
--- a/src/parser/PrismParser.cpp
+++ b/src/parser/PrismParser.cpp
@@ -105,10 +105,10 @@ namespace storm {
             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") > expressionParser) | qi::attr(manager->boolean(false))) > 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::_a = qi::_1]) | qi::attr(manager->boolean(false))) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_a)];
             booleanVariableDefinition.name("boolean variable definition");
             
-            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 = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expressionParser > 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)]);
@@ -210,7 +210,7 @@ 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
+            start = (qi::eps[phoenix::bind(&PrismParser::removeInitialConstruct, phoenix::ref(*this), qi::_a)]
                      > 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)]
@@ -278,7 +278,7 @@ namespace storm {
             return true;
         }
         
-        bool PrismParser::addInitialStatesConstruct(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
+        bool PrismParser::addInitialStatesConstruct(storm::expressions::Expression const& initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
             STORM_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;
@@ -587,7 +587,7 @@ namespace storm {
                     auto const& renamingPair = renaming.find(variable.getName());
                     STORM_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(manager->getVariable(renamingPair->second), variable.getInitialValueExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1)));
+                    booleanVariables.push_back(storm::prism::BooleanVariable(manager->getVariable(renamingPair->second), variable.hasInitialValue() ? variable.getInitialValueExpression().substitute(expressionRenaming) : variable.getInitialValueExpression(), this->getFilename(), get_line(qi::_1)));
                 }
                 
                 // Rename the integer variables.
@@ -596,7 +596,7 @@ namespace storm {
                     auto const& renamingPair = renaming.find(variable.getName());
                     STORM_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(manager->getVariable(renamingPair->second), variable.getLowerBoundExpression().substitute(expressionRenaming), variable.getUpperBoundExpression().substitute(expressionRenaming), variable.getInitialValueExpression().substitute(expressionRenaming), this->getFilename(), get_line(qi::_1)));
+                    integerVariables.push_back(storm::prism::IntegerVariable(manager->getVariable(renamingPair->second), variable.getLowerBoundExpression().substitute(expressionRenaming), variable.getUpperBoundExpression().substitute(expressionRenaming), variable.hasInitialValue() ? variable.getInitialValueExpression().substitute(expressionRenaming) : variable.getInitialValueExpression(), this->getFilename(), get_line(qi::_1)));
                 }
                 
                 // Rename commands.
@@ -642,7 +642,11 @@ namespace storm {
         }
         
         storm::prism::Program PrismParser::createProgram(GlobalProgramInformation const& globalProgramInformation) const {
-            return storm::prism::Program(manager, globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.actionIndices, globalProgramInformation.rewardModels, globalProgramInformation.labels, secondRun && !globalProgramInformation.hasInitialConstruct ? boost::none : boost::optional<storm::prism::InitialConstruct>(storm::prism::InitialConstruct(manager->boolean(false))), globalProgramInformation.systemCompositionConstruct, this->getFilename(), 1, this->secondRun);
+            return storm::prism::Program(manager, globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.actionIndices, globalProgramInformation.rewardModels, globalProgramInformation.labels, secondRun && !globalProgramInformation.hasInitialConstruct ? boost::none : boost::make_optional(globalProgramInformation.initialConstruct), globalProgramInformation.systemCompositionConstruct, this->getFilename(), 1, this->secondRun);
+        }
+        
+        void PrismParser::removeInitialConstruct(GlobalProgramInformation& globalProgramInformation) const {
+            globalProgramInformation.hasInitialConstruct = false;
         }
     } // namespace parser
 } // namespace storm
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 84a5b601e..2a83e3193 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -188,7 +188,7 @@ namespace storm {
             
             // 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::BooleanVariable(), qi::locals<storm::expressions::Expression>, Skipper> booleanVariableDefinition;
             qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
             
             // Rules for command definitions.
@@ -241,7 +241,7 @@ namespace storm {
             
             // Helper methods used in the grammar.
             bool isValidIdentifier(std::string const& identifier);
-            bool addInitialStatesConstruct(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
+            bool addInitialStatesConstruct(storm::expressions::Expression const& initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
             bool addSystemCompositionConstruct(std::shared_ptr<storm::prism::Composition> const& composition, GlobalProgramInformation& globalProgramInformation);
             
             
@@ -274,6 +274,8 @@ namespace storm {
             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;
             
+            void removeInitialConstruct(GlobalProgramInformation& globalProgramInformation) const;
+            
             // An error handler function.
             phoenix::function<SpiritErrorHandler> handler;
         };
diff --git a/src/storage/prism/BooleanVariable.cpp b/src/storage/prism/BooleanVariable.cpp
index c38812ec6..422b2266f 100644
--- a/src/storage/prism/BooleanVariable.cpp
+++ b/src/storage/prism/BooleanVariable.cpp
@@ -1,5 +1,7 @@
 #include "src/storage/prism/BooleanVariable.h"
 
+#include "src/storage/expressions/ExpressionManager.h"
+
 namespace storm {
     namespace prism {
         BooleanVariable::BooleanVariable(storm::expressions::Variable const& variable, storm::expressions::Expression const& initialValueExpression, std::string const& filename, uint_fast64_t lineNumber) : Variable(variable, initialValueExpression, false, filename, lineNumber) {
@@ -7,11 +9,21 @@ namespace storm {
         }
         
         BooleanVariable BooleanVariable::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
-            return BooleanVariable(this->getExpressionVariable(), this->getInitialValueExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
+            return BooleanVariable(this->getExpressionVariable(), this->getInitialValueExpression().isInitialized() ? this->getInitialValueExpression().substitute(substitution) : this->getInitialValueExpression(), this->getFilename(), this->getLineNumber());
+        }
+        
+        void BooleanVariable::createMissingInitialValue() {
+            if (!this->hasInitialValue()) {
+                this->setInitialValueExpression(this->getExpressionVariable().getManager().boolean(false));
+            }
         }
         
         std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable) {
-            stream << variable.getName() << ": bool init " << variable.getInitialValueExpression() << ";";
+            stream << variable.getName() << ": bool";
+            if (variable.hasInitialValue()) {
+                stream << " init " << variable.getInitialValueExpression();
+            }
+            stream << ";";
             return stream;
         }
         
diff --git a/src/storage/prism/BooleanVariable.h b/src/storage/prism/BooleanVariable.h
index 5b43e191c..c5c3ba8e4 100644
--- a/src/storage/prism/BooleanVariable.h
+++ b/src/storage/prism/BooleanVariable.h
@@ -37,6 +37,8 @@ namespace storm {
              */
             BooleanVariable substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const;
             
+            virtual void createMissingInitialValue() override;
+            
             friend std::ostream& operator<<(std::ostream& stream, BooleanVariable const& variable);
         };
         
diff --git a/src/storage/prism/IntegerVariable.cpp b/src/storage/prism/IntegerVariable.cpp
index b2306ece0..8b60b0e56 100644
--- a/src/storage/prism/IntegerVariable.cpp
+++ b/src/storage/prism/IntegerVariable.cpp
@@ -19,11 +19,21 @@ namespace storm {
         }
         
         IntegerVariable IntegerVariable::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
-            return IntegerVariable(this->getExpressionVariable(), this->getLowerBoundExpression().substitute(substitution), this->getUpperBoundExpression().substitute(substitution), this->getInitialValueExpression().substitute(substitution), this->getFilename(), this->getLineNumber());
+            return IntegerVariable(this->getExpressionVariable(), this->getLowerBoundExpression().substitute(substitution), this->getUpperBoundExpression().substitute(substitution), this->getInitialValueExpression().isInitialized() ? this->getInitialValueExpression().substitute(substitution) : this->getInitialValueExpression(), this->getFilename(), this->getLineNumber());
+        }
+        
+        void IntegerVariable::createMissingInitialValue() {
+            if (!this->hasInitialValue()) {
+                this->setInitialValueExpression(this->getLowerBoundExpression());
+            }
         }
         
         std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable) {
-            stream << variable.getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]" << " init " << variable.getInitialValueExpression() << ";";
+            stream << variable.getName() << ": [" << variable.getLowerBoundExpression() << ".." << variable.getUpperBoundExpression() << "]";
+            if (variable.hasInitialValue()) {
+                stream << " init " << variable.getInitialValueExpression();
+            }
+            stream << ";";
             return stream;
         }
     } // namespace prism
diff --git a/src/storage/prism/IntegerVariable.h b/src/storage/prism/IntegerVariable.h
index fc1c6ecf5..335c2ce05 100644
--- a/src/storage/prism/IntegerVariable.h
+++ b/src/storage/prism/IntegerVariable.h
@@ -60,6 +60,8 @@ namespace storm {
              */
             IntegerVariable substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const;
             
+            virtual void createMissingInitialValue() override;
+            
             friend std::ostream& operator<<(std::ostream& stream, IntegerVariable const& variable);
             
         private:
diff --git a/src/storage/prism/Module.cpp b/src/storage/prism/Module.cpp
index 755c4c78a..095ac3e11 100644
--- a/src/storage/prism/Module.cpp
+++ b/src/storage/prism/Module.cpp
@@ -42,7 +42,7 @@ namespace storm {
         std::vector<storm::prism::IntegerVariable> const& Module::getIntegerVariables() const {
             return this->integerVariables;
         }
-        
+
         std::set<storm::expressions::Variable> Module::getAllExpressionVariables() const {
             std::set<storm::expressions::Variable> result;
             for (auto const& var : this->getBooleanVariables()) {
@@ -221,6 +221,15 @@ namespace storm {
             return true;
         }
         
+        void Module::createMissingInitialValues() {
+            for (auto& variable : booleanVariables) {
+                variable.createMissingInitialValue();
+            }
+            for (auto& variable : integerVariables) {
+                variable.createMissingInitialValue();
+            }
+        }
+        
         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 df8a61c21..c3179b407 100644
--- a/src/storage/prism/Module.h
+++ b/src/storage/prism/Module.h
@@ -225,6 +225,11 @@ namespace storm {
              */
             bool containsVariablesOnlyInUpdateProbabilities(std::set<storm::expressions::Variable> const& undefinedConstantVariables) const;
             
+            /*!
+             * Equips all of the modules' variables without initial values with initial values based on their type.
+             */
+            void createMissingInitialValues();
+            
             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 cdc3d323a..3cf9df8ae 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -152,20 +152,26 @@ namespace storm {
             if (initialConstruct) {
                 this->initialConstruct = initialConstruct.get();
             } else {
+                // First, add all missing initial values.
+                this->createMissingInitialValues();
+                for (auto& modules : this->modules) {
+                    modules.createMissingInitialValues();
+                }
+                
                 // Create a new initial construct if none was given.
                 storm::expressions::Expression newInitialExpression = manager->boolean(true);
                 
-                for (auto const& booleanVariable : this->getGlobalBooleanVariables()) {
+                for (auto& booleanVariable : this->getGlobalBooleanVariables()) {
                     newInitialExpression = newInitialExpression && storm::expressions::iff(booleanVariable.getExpression(), booleanVariable.getInitialValueExpression());
                 }
-                for (auto const& integerVariable : this->getGlobalIntegerVariables()) {
+                for (auto& integerVariable : this->getGlobalIntegerVariables()) {
                     newInitialExpression = newInitialExpression && integerVariable.getExpression() == integerVariable.getInitialValueExpression();
                 }
-                for (auto const& module : this->getModules()) {
-                    for (auto const& booleanVariable : module.getBooleanVariables()) {
+                for (auto& module : this->getModules()) {
+                    for (auto& booleanVariable : module.getBooleanVariables()) {
                         newInitialExpression = newInitialExpression && storm::expressions::iff(booleanVariable.getExpression(), booleanVariable.getInitialValueExpression());
                     }
-                    for (auto const& integerVariable : module.getIntegerVariables()) {
+                    for (auto& integerVariable : module.getIntegerVariables()) {
                         newInitialExpression = newInitialExpression && integerVariable.getExpression() == integerVariable.getInitialValueExpression();
                     }
                 }
@@ -241,13 +247,17 @@ namespace storm {
             
             // Now check initial value expressions of global variables.
             for (auto const& booleanVariable : this->getGlobalBooleanVariables()) {
-                if (booleanVariable.getInitialValueExpression().containsVariable(undefinedConstantVariables)) {
-                    return false;
+                if (booleanVariable.hasInitialValue()) {
+                    if (booleanVariable.getInitialValueExpression().containsVariable(undefinedConstantVariables)) {
+                        return false;
+                    }
                 }
             }
             for (auto const& integerVariable : this->getGlobalIntegerVariables()) {
-                if (integerVariable.getInitialValueExpression().containsVariable(undefinedConstantVariables)) {
-                    return false;
+                if (integerVariable.hasInitialValue()) {
+                    if (integerVariable.getInitialValueExpression().containsVariable(undefinedConstantVariables)) {
+                        return false;
+                    }
                 }
                 if (integerVariable.getLowerBoundExpression().containsVariable(undefinedConstantVariables)) {
                     return false;
@@ -809,18 +819,20 @@ namespace storm {
             // Now we check the variable declarations. We start with the global variables.
             std::set<storm::expressions::Variable> variables;
             for (auto const& variable : this->getGlobalBooleanVariables()) {
-                // Check the initial value of the variable.
-                std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
-                std::set<storm::expressions::Variable> illegalVariables;
-                std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
-                bool isValid = illegalVariables.empty();
-                
-                if (!isValid) {
-                    std::vector<std::string> illegalVariableNames;
-                    for (auto const& var : illegalVariables) {
-                        illegalVariableNames.push_back(var.getName());
+                if (variable.hasInitialValue()) {
+                    // Check the initial value of the variable.
+                    std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
+                    std::set<storm::expressions::Variable> illegalVariables;
+                    std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
+                    bool isValid = illegalVariables.empty();
+                    
+                    if (!isValid) {
+                        std::vector<std::string> illegalVariableNames;
+                        for (auto const& var : illegalVariables) {
+                            illegalVariableNames.push_back(var.getName());
+                        }
+                        STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                     }
-                    STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                 }
                 
                 // Record the new identifier for future checks.
@@ -855,16 +867,18 @@ namespace storm {
                     STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                 }
                 
-                // Check the initial value of the variable.
-                containedVariables = variable.getInitialValueExpression().getVariables();
-                std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
-                isValid = illegalVariables.empty();
-                if (!isValid) {
-                    std::vector<std::string> illegalVariableNames;
-                    for (auto const& var : illegalVariables) {
-                        illegalVariableNames.push_back(var.getName());
+                if (variable.hasInitialValue()) {
+                    // Check the initial value of the variable.
+                    containedVariables = variable.getInitialValueExpression().getVariables();
+                    std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
+                    isValid = illegalVariables.empty();
+                    if (!isValid) {
+                        std::vector<std::string> illegalVariableNames;
+                        for (auto const& var : illegalVariables) {
+                            illegalVariableNames.push_back(var.getName());
+                        }
+                        STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                     }
-                    STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                 }
                 
                 // Record the new identifier for future checks.
@@ -877,17 +891,19 @@ namespace storm {
             // Now go through the variables of the modules.
             for (auto const& module : this->getModules()) {
                 for (auto const& variable : module.getBooleanVariables()) {
-                    // Check the initial value of the variable.
-                    std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
-                    std::set<storm::expressions::Variable> illegalVariables;
-                    std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
-                    bool isValid = illegalVariables.empty();
-                    if (!isValid) {
-                        std::vector<std::string> illegalVariableNames;
-                        for (auto const& var : illegalVariables) {
-                            illegalVariableNames.push_back(var.getName());
+                    if (variable.hasInitialValue()) {
+                        // Check the initial value of the variable.
+                        std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
+                        std::set<storm::expressions::Variable> illegalVariables;
+                        std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
+                        bool isValid = illegalVariables.empty();
+                        if (!isValid) {
+                            std::vector<std::string> illegalVariableNames;
+                            for (auto const& var : illegalVariables) {
+                                illegalVariableNames.push_back(var.getName());
+                            }
+                            STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                         }
-                        STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                     }
                     
                     // Record the new identifier for future checks.
@@ -920,17 +936,19 @@ namespace storm {
                         STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": upper bound expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                     }
                     
-                    // Check the initial value of the variable.
-                    containedVariables = variable.getInitialValueExpression().getVariables();
-                    illegalVariables.clear();
-                    std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
-                    isValid = illegalVariables.empty();
-                    if (!isValid) {
-                        std::vector<std::string> illegalVariableNames;
-                        for (auto const& var : illegalVariables) {
-                            illegalVariableNames.push_back(var.getName());
+                    if (variable.hasInitialValue()) {
+                        // Check the initial value of the variable.
+                        containedVariables = variable.getInitialValueExpression().getVariables();
+                        illegalVariables.clear();
+                        std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(), std::inserter(illegalVariables, illegalVariables.begin()));
+                        isValid = illegalVariables.empty();
+                        if (!isValid) {
+                            std::vector<std::string> illegalVariableNames;
+                            for (auto const& var : illegalVariables) {
+                                illegalVariableNames.push_back(var.getName());
+                            }
+                            STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                         }
-                        STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames, ",") << ".");
                     }
                     
                     // Record the new identifier for future checks.
@@ -1571,7 +1589,7 @@ namespace storm {
             }
             storm::jani::Model janiModel("jani_from_prism", modelType, 1, manager);
             storm::expressions::Expression globalInitialStatesExpression;
-
+            
             // Add all constants of the PRISM program to the JANI model.
             for (auto const& constant : constants) {
                 janiModel.addConstant(storm::jani::Constant(constant.getName(), constant.getExpressionVariable(), constant.isDefined() ? boost::optional<storm::expressions::Expression>(constant.getExpression()) : boost::none));
@@ -1580,13 +1598,17 @@ namespace storm {
             // Add all global variables of the PRISM program to the JANI model.
             for (auto const& variable : globalIntegerVariables) {
                 janiModel.addBoundedIntegerVariable(storm::jani::BoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.getLowerBoundExpression(), variable.getUpperBoundExpression()));
-                storm::expressions::Expression variableInitialExpression = variable.getExpressionVariable() == variable.getInitialValueExpression();
-                globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                if (variable.hasInitialValue()) {
+                    storm::expressions::Expression variableInitialExpression = variable.getExpressionVariable() == variable.getInitialValueExpression();
+                    globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                }
             }
             for (auto const& variable : globalBooleanVariables) {
                 janiModel.addBooleanVariable(storm::jani::BooleanVariable(variable.getName(), variable.getExpressionVariable()));
-                storm::expressions::Expression variableInitialExpression = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
-                globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                if (variable.hasInitialValue()) {
+                    storm::expressions::Expression variableInitialExpression = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                    globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                }
             }
             
             // Add all actions of the PRISM program to the JANI model.
@@ -1598,7 +1620,7 @@ namespace storm {
             }
             
             // Because of the rules of JANI, we have to make all variables of modules global that are read by other modules.
-
+            
             // Create a mapping from variables to the indices of module indices that write/read the variable.
             std::map<storm::expressions::Variable, std::set<uint_fast64_t>> variablesToAccessingModuleIndices;
             for (uint_fast64_t index = 0; index < modules.size(); ++index) {
@@ -1627,20 +1649,24 @@ namespace storm {
             for (auto const& module : modules) {
                 storm::jani::Automaton automaton(module.getName());
                 storm::expressions::Expression initialStatesExpression;
-
+                
                 for (auto const& variable : module.getIntegerVariables()) {
                     storm::jani::BoundedIntegerVariable newIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.getLowerBoundExpression(), variable.getUpperBoundExpression());
                     std::set<uint_fast64_t> const& accessingModuleIndices = variablesToAccessingModuleIndices[variable.getExpressionVariable()];
                     // If there is exactly one module reading and writing the variable, we can make the variable local to this module.
                     if (!allVariablesGlobal && accessingModuleIndices.size() == 1) {
                         automaton.addBoundedIntegerVariable(newIntegerVariable);
-                        storm::expressions::Expression variableInitialExpression = variable.getExpressionVariable() == variable.getInitialValueExpression();
-                        initialStatesExpression = initialStatesExpression.isInitialized() ? initialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        if (variable.hasInitialValue()) {
+                            storm::expressions::Expression variableInitialExpression = variable.getExpressionVariable() == variable.getInitialValueExpression();
+                            initialStatesExpression = initialStatesExpression.isInitialized() ? initialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        }
                     } else if (!accessingModuleIndices.empty()) {
                         // Otherwise, we need to make it global.
                         janiModel.addBoundedIntegerVariable(newIntegerVariable);
-                        storm::expressions::Expression variableInitialExpression = variable.getExpressionVariable() == variable.getInitialValueExpression();
-                        globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        if (variable.hasInitialValue()) {
+                            storm::expressions::Expression variableInitialExpression = variable.getExpressionVariable() == variable.getInitialValueExpression();
+                            globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        }
                     }
                 }
                 for (auto const& variable : module.getBooleanVariables()) {
@@ -1649,13 +1675,17 @@ namespace storm {
                     // If there is exactly one module reading and writing the variable, we can make the variable local to this module.
                     if (!allVariablesGlobal && accessingModuleIndices.size() == 1) {
                         automaton.addBooleanVariable(newBooleanVariable);
-                        storm::expressions::Expression variableInitialExpression = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
-                        initialStatesExpression = initialStatesExpression.isInitialized() ? initialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        if (variable.hasInitialValue()) {
+                            storm::expressions::Expression variableInitialExpression = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                            initialStatesExpression = initialStatesExpression.isInitialized() ? initialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        }
                     } else if (!accessingModuleIndices.empty()) {
                         // Otherwise, we need to make it global.
                         janiModel.addBooleanVariable(newBooleanVariable);
-                        storm::expressions::Expression variableInitialExpression = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
-                        globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        if (variable.hasInitialValue()) {
+                            storm::expressions::Expression variableInitialExpression = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                            globalInitialStatesExpression = globalInitialStatesExpression.isInitialized() ? globalInitialStatesExpression && variableInitialExpression : variableInitialExpression;
+                        }
                     }
                 }
                 
@@ -1713,6 +1743,19 @@ namespace storm {
             return janiModel;
         }
         
+        void Program::createMissingInitialValues() {
+            for (auto& variable : globalBooleanVariables) {
+                if (!variable.hasInitialValue()) {
+                    variable.setInitialValueExpression(manager->boolean(false));
+                }
+            }
+            for (auto& variable : globalIntegerVariables) {
+                if (!variable.hasInitialValue()) {
+                    variable.setInitialValueExpression(variable.getLowerBoundExpression());
+                }
+            }
+        }
+        
         std::ostream& operator<<(std::ostream& out, Program::ModelType const& type) {
             switch (type) {
                 case Program::ModelType::UNDEFINED: out << "undefined"; break;
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 8c30079e0..50bd84603 100644
--- a/src/storage/prism/Program.h
+++ b/src/storage/prism/Program.h
@@ -175,7 +175,7 @@ namespace storm {
              * @return The global boolean variables of the program.
              */
             std::vector<BooleanVariable> const& getGlobalBooleanVariables() const;
-            
+
             /*!
              * Retrieves a the global boolean variable with the given name.
              *
@@ -587,6 +587,11 @@ namespace storm {
              */
             Command synchronizeCommands(uint_fast64_t newCommandIndex, uint_fast64_t actionIndex, uint_fast64_t firstUpdateIndex, std::string const& actionName, std::vector<std::reference_wrapper<Command const>> const& commands) const;
             
+            /*!
+             * Equips all global variables without initial values with initial values based on their type.
+             */
+            void createMissingInitialValues();
+            
             // The manager responsible for the variables/expressions of the program.
             std::shared_ptr<storm::expressions::ExpressionManager> manager;
             
diff --git a/src/storage/prism/Variable.cpp b/src/storage/prism/Variable.cpp
index 7d347bcec..cda8317a5 100644
--- a/src/storage/prism/Variable.cpp
+++ b/src/storage/prism/Variable.cpp
@@ -5,11 +5,11 @@
 
 namespace storm {
     namespace prism {
-        Variable::Variable(storm::expressions::Variable const& variable, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variable(variable), initialValueExpression(initialValueExpression), defaultInitialValue(defaultInitialValue) {
+        Variable::Variable(storm::expressions::Variable const& variable, storm::expressions::Expression const& initialValueExpression, bool defaultInitialValue, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variable(variable), initialValueExpression(initialValueExpression) {
             // Nothing to do here.
         }
         
-        Variable::Variable(storm::expressions::ExpressionManager& manager, Variable const& oldVariable, std::string const& newName, std::map<storm::expressions::Variable, storm::expressions::Expression> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variable(manager.declareVariable(newName, oldVariable.variable.getType())), initialValueExpression(oldVariable.getInitialValueExpression().substitute(renaming)), defaultInitialValue(oldVariable.hasDefaultInitialValue()) {
+        Variable::Variable(storm::expressions::ExpressionManager& manager, Variable const& oldVariable, std::string const& newName, std::map<storm::expressions::Variable, storm::expressions::Expression> const& renaming, std::string const& filename, uint_fast64_t lineNumber) : LocatedInformation(filename, lineNumber), variable(manager.declareVariable(newName, oldVariable.variable.getType())), initialValueExpression(oldVariable.getInitialValueExpression().substitute(renaming)) {
             // Intentionally left empty.
         }
         
@@ -17,14 +17,18 @@ namespace storm {
             return this->variable.getName();
         }
         
-        bool Variable::hasDefaultInitialValue() const {
-            return this->defaultInitialValue;
+        bool Variable::hasInitialValue() const {
+            return this->initialValueExpression.isInitialized();
         }
 
         storm::expressions::Expression const& Variable::getInitialValueExpression() const {
             return this->initialValueExpression;
         }
         
+        void Variable::setInitialValueExpression(storm::expressions::Expression const& initialValueExpression) {
+            this->initialValueExpression = initialValueExpression;
+        }
+        
         storm::expressions::Variable const& Variable::getExpressionVariable() const {
             return this->variable;
         }
diff --git a/src/storage/prism/Variable.h b/src/storage/prism/Variable.h
index 3a19c2b75..40f47eb27 100644
--- a/src/storage/prism/Variable.h
+++ b/src/storage/prism/Variable.h
@@ -28,19 +28,27 @@ namespace storm {
             std::string const& getName() const;
             
             /*!
-             * Retrieves the expression defining the initial value of the variable.
+             * Retrieves whether the variable has an initial value.
+             *
+             * @return True iff the variable has an initial value.
+             */
+            bool hasInitialValue() const;
+            
+            /*!
+             * Retrieves the expression defining the initial value of the variable. This can only be called if there is
+             * an initial value (expression).
              *
              * @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.
+             * Sets the expression defining the initial value of the variable.
              *
-             * @return True iff the variable has the default initial value.
+             * @param initialValueExpression The expression defining the initial value of the variable.
              */
-            bool hasDefaultInitialValue() const;
-            
+            void setInitialValueExpression(storm::expressions::Expression const& initialValueExpression);
+
             /*!
              * Retrieves the expression variable associated with this variable.
              *
@@ -55,6 +63,10 @@ namespace storm {
              */
             storm::expressions::Expression getExpression() const;
             
+            /*!
+             * Equips the variable with an initial value based on its type if not initial value is present.
+             */
+            virtual void createMissingInitialValue() = 0;
             
             // Make the constructors protected to forbid instantiation of this class.
         protected:
@@ -90,9 +102,6 @@ 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