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)
diff --git a/src/adapters/AddExpressionAdapter.cpp b/src/adapters/AddExpressionAdapter.cpp
index e50620db8..2f0dc7190 100644
--- a/src/adapters/AddExpressionAdapter.cpp
+++ b/src/adapters/AddExpressionAdapter.cpp
@@ -194,8 +194,8 @@ 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()));
+        boost::any AddExpressionAdapter<Type, ValueType>::visit(storm::expressions::RationalLiteralExpression const& expression) {
+            return ddManager->getConstant(static_cast<ValueType>(expression.getValueAsDouble()));
         }
         
         // Explicitly instantiate the symbolic expression adapter
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 9fec0cf15..77b39cc68 100644
--- a/src/adapters/MathsatExpressionAdapter.h
+++ b/src/adapters/MathsatExpressionAdapter.h
@@ -171,8 +171,8 @@ namespace storm {
                 return expression.getValue() ? msat_make_true(env) : msat_make_false(env);
 			}
 
-			virtual boost::any visit(expressions::DoubleLiteralExpression const& expression) override {
-				return msat_make_number(env, std::to_string(expression.getValue()).c_str());
+			virtual boost::any visit(expressions::RationalLiteralExpression const& expression) override {
+				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/adapters/Z3ExpressionAdapter.cpp b/src/adapters/Z3ExpressionAdapter.cpp
index 60b4e8e1c..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 << ".");
                 }
@@ -208,7 +210,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/builder/DdPrismModelBuilder.cpp b/src/builder/DdPrismModelBuilder.cpp
index a397b0de0..6c495e15c 100644
--- a/src/builder/DdPrismModelBuilder.cpp
+++ b/src/builder/DdPrismModelBuilder.cpp
@@ -1415,7 +1415,7 @@ namespace storm {
         
         template <storm::dd::DdType Type, typename ValueType>
         storm::dd::Bdd<Type> DdPrismModelBuilder<Type, ValueType>::createInitialStatesDecisionDiagram(GenerationInformation& generationInfo) {
-            storm::dd::Bdd<Type> initialStates = generationInfo.rowExpressionAdapter->translateExpression(generationInfo.program.getInitialConstruct().getInitialStatesExpression()).toBdd();
+            storm::dd::Bdd<Type> initialStates = generationInfo.rowExpressionAdapter->translateExpression(generationInfo.program.getInitialStatesExpression()).toBdd();
             
             for (auto const& metaVariable : generationInfo.rowMetaVariables) {
                 initialStates &= generationInfo.manager->getRange(metaVariable);
diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h
index 44ebb71ec..64665a8fc 100644
--- a/src/counterexamples/SMTMinimalCommandSetGenerator.h
+++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h
@@ -628,7 +628,7 @@ namespace storm {
                 }
                 
                 // Construct an expression that exactly characterizes the initial state.
-                storm::expressions::Expression initialStateExpression = program.getInitialConstruct().getInitialStatesExpression();
+                storm::expressions::Expression initialStateExpression = program.getInitialStatesExpression();
                 
                 // Store the found implications in a container similar to the preceding label sets.
                 std::map<boost::container::flat_set<uint_fast64_t>, std::set<boost::container::flat_set<uint_fast64_t>>> backwardImplications;
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..6e1aeafdb 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);
@@ -136,7 +137,7 @@ namespace storm {
             for (auto const& expression : rangeExpressions) {
                 solver->add(expression);
             }
-            solver->add(program.getInitialConstruct().getInitialStatesExpression());
+            solver->add(program.getInitialStatesExpression());
             
             // Proceed ss long as the solver can still enumerate initial states.
             std::vector<StateType> initialStateIndices;
@@ -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/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index 616dcf828..660906acb 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/symbolic/StandardRewardModel.h"
 #include "src/storage/dd/Add.h"
 #include "src/storage/dd/Bdd.h"
 
diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp
index 20982bd20..3054f2fe0 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::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;
@@ -295,7 +323,7 @@ namespace storm {
             return manager->boolean(false);
         }
                 
-        storm::expressions::Expression ExpressionParser::createDoubleLiteralExpression(double 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 66d851707..077be8db2 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 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/parser/JaniParser.h b/src/parser/JaniParser.h
index 82165b5ef..80b4ca0d7 100644
--- a/src/parser/JaniParser.h
+++ b/src/parser/JaniParser.h
@@ -42,7 +42,8 @@ namespace storm {
             storm::jani::Property parseProperty(json const& propertyStructure);
             storm::jani::Automaton parseAutomaton(json const& automatonStructure, storm::jani::Model const& parentModel);
             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:
             std::shared_ptr<storm::jani::Constant> parseConstant(json const& constantStructure, std::string const& scopeDescription = "global");
 
diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp
index 7d54f18c6..d3e5191e2 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;
         }
         
@@ -103,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)]);
@@ -208,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)]
@@ -276,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;
@@ -585,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.
@@ -594,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.
@@ -640,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/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
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
deleted file mode 100644
index cab9fc31b..000000000
--- a/src/storage/expressions/DoubleLiteralExpression.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "src/storage/expressions/DoubleLiteralExpression.h"
-#include "src/storage/expressions/ExpressionManager.h"
-#include "src/storage/expressions/ExpressionVisitor.h"
-
-namespace storm {
-    namespace expressions {
-        DoubleLiteralExpression::DoubleLiteralExpression(ExpressionManager const& manager, double value) : BaseExpression(manager, manager.getRationalType()), value(value) {
-            // Intentionally left empty.
-        }
-        
-        double DoubleLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
-            return this->getValue();
-        }
-        
-        bool DoubleLiteralExpression::isLiteral() const {
-            return true;
-        }
-        
-        void DoubleLiteralExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const {
-            return;
-		}
-        
-        std::shared_ptr<BaseExpression const> DoubleLiteralExpression::simplify() const {
-            return this->shared_from_this();
-        }
-        
-        boost::any DoubleLiteralExpression::accept(ExpressionVisitor& visitor) const {
-            return visitor.visit(*this);
-        }
-        
-        double DoubleLiteralExpression::getValue() const {
-            return this->value;
-        }
-        
-        void DoubleLiteralExpression::printToStream(std::ostream& stream) const {
-            stream << this->getValue();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/storage/expressions/DoubleLiteralExpression.h b/src/storage/expressions/DoubleLiteralExpression.h
deleted file mode 100644
index 676291a77..000000000
--- a/src/storage/expressions/DoubleLiteralExpression.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
-#define STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
-
-#include "src/storage/expressions/BaseExpression.h"
-#include "src/utility/OsDetection.h"
-
-namespace storm {
-    namespace expressions {
-        class DoubleLiteralExpression : public BaseExpression {
-        public:
-            /*!
-             * Creates an double literal expression with the given value.
-             *
-             * @param manager The manager responsible for this expression.
-             * @param value The value of the double literal.
-             */
-            DoubleLiteralExpression(ExpressionManager const& manager, double value);
-            
-            // Instantiate constructors and assignments with their default implementations.
-            DoubleLiteralExpression(DoubleLiteralExpression const& other) = default;
-            DoubleLiteralExpression& operator=(DoubleLiteralExpression const& other) = delete;
-#ifndef WINDOWS
-            DoubleLiteralExpression(DoubleLiteralExpression&&) = default;
-            DoubleLiteralExpression& operator=(DoubleLiteralExpression&&) = delete;
-#endif
-            virtual ~DoubleLiteralExpression() = default;
-            
-            // Override base class methods.
-            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
-            virtual bool isLiteral() const override;
-            virtual void gatherVariables(std::set<storm::expressions::Variable>& variables) const override;
-            virtual std::shared_ptr<BaseExpression const> simplify() const override;
-            virtual boost::any accept(ExpressionVisitor& visitor) const override;
-
-            /*!
-             * Retrieves the value of the double literal.
-             *
-             * @return The value of the double literal.
-             */
-            double getValue() const;
-            
-        protected:
-            // Override base class method.
-            virtual void printToStream(std::ostream& stream) const override;
-            
-        private:
-            // The value of the double literal.
-            double value;
-        };
-    }
-}
-
-#endif /* STORM_STORAGE_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionManager.cpp b/src/storage/expressions/ExpressionManager.cpp
index d1add4402..ed51f76ee 100644
--- a/src/storage/expressions/ExpressionManager.cpp
+++ b/src/storage/expressions/ExpressionManager.cpp
@@ -65,7 +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 RationalLiteralExpression(*this, value)));
         }
         
         bool ExpressionManager::operator==(ExpressionManager const& other) const {
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.
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 8d7f39278..dc9a909f9 100644
--- a/src/storage/expressions/LinearCoefficientVisitor.cpp
+++ b/src/storage/expressions/LinearCoefficientVisitor.cpp
@@ -151,8 +151,8 @@ namespace storm {
             return VariableCoefficients(static_cast<double>(expression.getValue()));
         }
         
-        boost::any LinearCoefficientVisitor::visit(DoubleLiteralExpression const& expression) {
-            return VariableCoefficients(expression.getValue());
+        boost::any LinearCoefficientVisitor::visit(RationalLiteralExpression const& expression) {
+            return VariableCoefficients(expression.getValueAsDouble());
         }
     }
 }
\ No newline at end of file
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/RationalLiteralExpression.cpp b/src/storage/expressions/RationalLiteralExpression.cpp
new file mode 100644
index 000000000..3fa226a8a
--- /dev/null
+++ b/src/storage/expressions/RationalLiteralExpression.cpp
@@ -0,0 +1,53 @@
+#include "src/storage/expressions/RationalLiteralExpression.h"
+#include "src/storage/expressions/ExpressionManager.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+
+#include "src/utility/constants.h"
+
+namespace storm {
+    namespace expressions {
+        RationalLiteralExpression::RationalLiteralExpression(ExpressionManager const& manager, double value) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(value)) {
+            // Intentionally left empty.
+        }
+        
+        RationalLiteralExpression::RationalLiteralExpression(ExpressionManager const& manager, std::string const& valueAsString) : BaseExpression(manager, manager.getRationalType()), value(storm::utility::convertNumber<storm::RationalNumber>(valueAsString)) {
+            // Intentionally left empty.
+        }
+        
+        RationalLiteralExpression::RationalLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value) : BaseExpression(manager, manager.getRationalType()), value(value) {
+            // Intentionally left empty.
+        }
+        
+        double RationalLiteralExpression::evaluateAsDouble(Valuation const* valuation) const {
+            return this->getValueAsDouble();
+        }
+        
+        bool RationalLiteralExpression::isLiteral() const {
+            return true;
+        }
+        
+        void RationalLiteralExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const {
+            return;
+		}
+        
+        std::shared_ptr<BaseExpression const> RationalLiteralExpression::simplify() const {
+            return this->shared_from_this();
+        }
+        
+        boost::any RationalLiteralExpression::accept(ExpressionVisitor& visitor) const {
+            return visitor.visit(*this);
+        }
+        
+        double RationalLiteralExpression::getValueAsDouble() const {
+            return storm::utility::convertNumber<double>(this->value);
+        }
+        
+        storm::RationalNumber RationalLiteralExpression::getValue() const {
+            return this->value;
+        }
+        
+        void RationalLiteralExpression::printToStream(std::ostream& stream) const {
+            stream << this->getValue();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/RationalLiteralExpression.h b/src/storage/expressions/RationalLiteralExpression.h
new file mode 100644
index 000000000..4eff900b2
--- /dev/null
+++ b/src/storage/expressions/RationalLiteralExpression.h
@@ -0,0 +1,78 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_RationalLiteralExpression_H_
+#define STORM_STORAGE_EXPRESSIONS_RationalLiteralExpression_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+#include "src/utility/OsDetection.h"
+
+#include "src/adapters/CarlAdapter.h"
+
+namespace storm {
+    namespace expressions {
+        class RationalLiteralExpression : public BaseExpression {
+        public:
+            /*!
+             * Creates an double literal expression with the given value.
+             *
+             * @param manager The manager responsible for this expression.
+             * @param value The value of the double literal.
+             */
+            RationalLiteralExpression(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.
+             */
+            RationalLiteralExpression(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.
+             */
+            RationalLiteralExpression(ExpressionManager const& manager, storm::RationalNumber const& value);
+
+            // Instantiate constructors and assignments with their default implementations.
+            RationalLiteralExpression(RationalLiteralExpression const& other) = default;
+            RationalLiteralExpression& operator=(RationalLiteralExpression const& other) = delete;
+#ifndef WINDOWS
+            RationalLiteralExpression(RationalLiteralExpression&&) = default;
+            RationalLiteralExpression& operator=(RationalLiteralExpression&&) = delete;
+#endif
+            virtual ~RationalLiteralExpression() = default;
+            
+            // Override base class methods.
+            virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override;
+            virtual bool isLiteral() const override;
+            virtual void gatherVariables(std::set<storm::expressions::Variable>& variables) const override;
+            virtual std::shared_ptr<BaseExpression const> simplify() const override;
+            virtual boost::any accept(ExpressionVisitor& visitor) const override;
+
+            /*!
+             * Retrieves the value of the double literal.
+             *
+             * @return The value of the double literal.
+             */
+            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 literal.
+            storm::RationalNumber value;
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_RationalLiteralExpression_H_ */
\ No newline at end of file
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 1a3dd0fc3..a219066e4 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"
 
@@ -33,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;
@@ -46,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.");
             }
@@ -92,8 +99,8 @@ namespace storm {
         }
         
         template<typename RationalFunctionType>
-        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(DoubleLiteralExpression const& expression) {
-            return RationalFunctionType(carl::rationalize<storm::RationalNumber>(expression.getValue()));
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(RationalLiteralExpression const& expression) {
+            return storm::utility::convertNumber<storm::RationalFunction>(expression.getValue());
         }
 
         template class ToRationalFunctionVisitor<storm::RationalFunction>;
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 785f36950..1b7319927 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();
         }
         
@@ -86,9 +97,9 @@ 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 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/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));
                 }
             }
             
diff --git a/src/storage/jani/BooleanVariable.cpp b/src/storage/jani/BooleanVariable.cpp
index b7a4c4e19..3eb63780b 100644
--- a/src/storage/jani/BooleanVariable.cpp
+++ b/src/storage/jani/BooleanVariable.cpp
@@ -11,10 +11,17 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        
         bool BooleanVariable::isBooleanVariable() const {
             return true;
         }
         
+        std::shared_ptr<BooleanVariable> makeBooleanVariable(std::string const& name, storm::expressions::Variable const& variable, boost::optional<storm::expressions::Expression> initValue, bool transient) {
+            if (initValue) {
+                return std::make_shared<BooleanVariable>(name, variable, initValue.get(), transient);
+            } else {
+                return std::make_shared<BooleanVariable>(name, variable, transient);
+            }
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/src/storage/jani/BooleanVariable.h b/src/storage/jani/BooleanVariable.h
index 7a8fe8b21..7fe9603e0 100644
--- a/src/storage/jani/BooleanVariable.h
+++ b/src/storage/jani/BooleanVariable.h
@@ -21,5 +21,10 @@ namespace storm {
             virtual bool isBooleanVariable() const override;
         };
         
+        /**
+         * Convenience function to call the appropriate constructor and return a shared pointer to the variable.
+         */
+        std::shared_ptr<BooleanVariable> makeBooleanVariable(std::string const& name, storm::expressions::Variable const& variable, boost::optional<storm::expressions::Expression> initValue, bool transient);
+        
     }
 }
\ No newline at end of file
diff --git a/src/storage/jani/BoundedIntegerVariable.cpp b/src/storage/jani/BoundedIntegerVariable.cpp
index f0872a500..58173bb76 100644
--- a/src/storage/jani/BoundedIntegerVariable.cpp
+++ b/src/storage/jani/BoundedIntegerVariable.cpp
@@ -47,10 +47,8 @@ namespace storm {
         }
         
         std::shared_ptr<BoundedIntegerVariable> makeBoundedIntegerVariable(std::string const& name, storm::expressions::Variable const& variable, boost::optional<storm::expressions::Expression> initValue, bool transient, boost::optional<storm::expressions::Expression> lowerBound, boost::optional<storm::expressions::Expression> upperBound) {
-            if(!lowerBound || !upperBound) {
-                STORM_LOG_THROW(lowerBound && upperBound, storm::exceptions::NotImplementedException, "Jani Bounded Integer variables (for now) have to be bounded from both sides");
-            }
-            if(initValue) {
+            STORM_LOG_THROW(lowerBound && upperBound, storm::exceptions::NotImplementedException, "Jani Bounded Integer variables (for now) have to be bounded from both sides");
+            if (initValue) {
                 return std::make_shared<BoundedIntegerVariable>(name, variable, initValue.get(), transient, lowerBound.get(), upperBound.get());
             } else {
                 return std::make_shared<BoundedIntegerVariable>(name, variable, transient, lowerBound.get(), upperBound.get());
diff --git a/src/storage/jani/BoundedIntegerVariable.h b/src/storage/jani/BoundedIntegerVariable.h
index c9a42b177..1c68bd239 100644
--- a/src/storage/jani/BoundedIntegerVariable.h
+++ b/src/storage/jani/BoundedIntegerVariable.h
@@ -61,7 +61,7 @@ namespace storm {
         };
         
         /**
-         * Convenience function to call the appropriate constructor and retur a shared pointer to the variable.
+         * Convenience function to call the appropriate constructor and return a shared pointer to the variable.
          */
         std::shared_ptr<BoundedIntegerVariable> makeBoundedIntegerVariable(std::string const& name, storm::expressions::Variable const& variable, boost::optional<storm::expressions::Expression> initValue, bool transient, boost::optional<storm::expressions::Expression> lowerBound, boost::optional<storm::expressions::Expression> upperBound);
     }
diff --git a/src/storage/jani/UnboundedIntegerVariable.h b/src/storage/jani/UnboundedIntegerVariable.h
index d3d3daa01..17f81d334 100644
--- a/src/storage/jani/UnboundedIntegerVariable.h
+++ b/src/storage/jani/UnboundedIntegerVariable.h
@@ -15,7 +15,6 @@ namespace storm {
              * Creates an unbounded integer variable with initial value.
              */
             UnboundedIntegerVariable(std::string const& name, storm::expressions::Variable const& variable, storm::expressions::Expression const&, bool transient=false);
-
             
             virtual bool isUnboundedIntegerVariable() const override;
         };
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/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/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 d4168196d..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()) {
@@ -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());
@@ -216,12 +213,23 @@ namespace storm {
             }
             
             for (auto const& command : this->getCommands()) {
-                command.containsVariablesOnlyInUpdateProbabilities(undefinedConstantVariables);
+                if (!command.containsVariablesOnlyInUpdateProbabilities(undefinedConstantVariables)) {
+                    return false;
+                }
             }
             
             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 620432580..c3179b407 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.
@@ -226,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 3562747e7..a836b5879 100644
--- a/src/storage/prism/Program.cpp
+++ b/src/storage/prism/Program.cpp
@@ -148,28 +148,15 @@ namespace storm {
             // Start by creating the necessary mappings from the given ones.
             this->createMappings();
             
-            // Set the initial construct.
+            // Set the initial construct if given.
             if (initialConstruct) {
                 this->initialConstruct = initialConstruct.get();
             } else {
-                // Create a new initial construct if none was given.
-                storm::expressions::Expression newInitialExpression = manager->boolean(true);
-                
-                for (auto const& booleanVariable : this->getGlobalBooleanVariables()) {
-                    newInitialExpression = newInitialExpression && storm::expressions::iff(booleanVariable.getExpression(), booleanVariable.getInitialValueExpression());
-                }
-                for (auto const& integerVariable : this->getGlobalIntegerVariables()) {
-                    newInitialExpression = newInitialExpression && integerVariable.getExpression() == integerVariable.getInitialValueExpression();
-                }
-                for (auto const& module : this->getModules()) {
-                    for (auto const& booleanVariable : module.getBooleanVariables()) {
-                        newInitialExpression = newInitialExpression && storm::expressions::iff(booleanVariable.getExpression(), booleanVariable.getInitialValueExpression());
-                    }
-                    for (auto const& integerVariable : module.getIntegerVariables()) {
-                        newInitialExpression = newInitialExpression && integerVariable.getExpression() == integerVariable.getInitialValueExpression();
-                    }
+                // Otherwise, we create the missing initial values.
+                this->createMissingInitialValues();
+                for (auto& modules : this->modules) {
+                    modules.createMissingInitialValues();
                 }
-                this->initialConstruct = storm::prism::InitialConstruct(newInitialExpression, this->getInitialConstruct().getFilename(), this->getInitialConstruct().getLineNumber());
             }
             
             if (finalModel) {
@@ -230,7 +217,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)) {
@@ -241,13 +228,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;
@@ -266,7 +257,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.
@@ -275,8 +268,10 @@ namespace storm {
             }
             
             // Initial construct.
-            if (this->getInitialConstruct().getInitialStatesExpression().containsVariable(undefinedConstantVariables)) {
-                return false;
+            if (this->hasInitialConstruct()) {
+                if (this->getInitialConstruct().getInitialStatesExpression().containsVariable(undefinedConstantVariables)) {
+                    return false;
+                }
             }
             
             // Labels.
@@ -446,10 +441,61 @@ namespace storm {
             return actionToIndexMap;
         }
         
+        bool Program::hasInitialConstruct() const {
+            return static_cast<bool>(initialConstruct);
+        }
+        
         storm::prism::InitialConstruct const& Program::getInitialConstruct() const {
+            return this->initialConstruct.get();
+        }
+        
+        boost::optional<InitialConstruct> const& Program::getOptionalInitialConstruct() const {
             return this->initialConstruct;
         }
         
+        storm::expressions::Expression Program::getInitialStatesExpression() const {
+            // If there is an initial construct, return its expression. If not, we construct the expression from the
+            // initial values of the variables (which have to exist).
+            if (this->hasInitialConstruct()) {
+                return this->getInitialConstruct().getInitialStatesExpression();
+            } else {
+                storm::expressions::Expression result;
+                
+                for (auto const& variable : this->getGlobalBooleanVariables()) {
+                    if (result.isInitialized()) {
+                        result = result && storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                    } else {
+                        result = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                    }
+                }
+                for (auto const& variable : this->getGlobalIntegerVariables()) {
+                    if (result.isInitialized()) {
+                        result = result && variable.getExpressionVariable() == variable.getInitialValueExpression();
+                    } else {
+                        result = variable.getExpressionVariable() == variable.getInitialValueExpression();
+                    }
+                }
+                for (auto const& module : this->getModules()) {
+                    for (auto const& variable : module.getBooleanVariables()) {
+                        if (result.isInitialized()) {
+                            result = result && storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                        } else {
+                            result = storm::expressions::iff(variable.getExpressionVariable(), variable.getInitialValueExpression());
+                        }
+                    }
+                    for (auto const& variable : module.getIntegerVariables()) {
+                        if (result.isInitialized()) {
+                            result = result && variable.getExpressionVariable() == variable.getInitialValueExpression();
+                        } else {
+                            result = variable.getExpressionVariable() == variable.getInitialValueExpression();
+                        }
+                    }
+                }
+                
+                return result;
+            }
+        }
+        
         bool Program::specifiesSystemComposition() const {
             return static_cast<bool>(systemCompositionConstruct);
         }
@@ -611,7 +657,7 @@ namespace storm {
                 newModules.push_back(module.restrictCommands(indexSet));
             }
             
-            return Program(this->manager, this->getModelType(), this->getConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getActionNameToIndexMapping(), this->getRewardModels(), this->getLabels(), this->getInitialConstruct(), this->getOptionalSystemCompositionConstruct());
+            return Program(this->manager, this->getModelType(), this->getConstants(), this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), newModules, this->getActionNameToIndexMapping(), this->getRewardModels(), this->getLabels(), this->getOptionalInitialConstruct(), this->getOptionalSystemCompositionConstruct());
         }
         
         void Program::createMappings() {
@@ -711,11 +757,11 @@ namespace storm {
                 STORM_LOG_THROW(definedUndefinedConstants.find(constantExpressionPair.first) != definedUndefinedConstants.end(), storm::exceptions::InvalidArgumentException, "Unable to define non-existant constant.");
             }
             
-            return Program(this->manager, this->getModelType(), newConstants, this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), this->getModules(), this->getActionNameToIndexMapping(), this->getRewardModels(), this->getLabels(), this->getInitialConstruct(), this->getOptionalSystemCompositionConstruct());
+            return Program(this->manager, this->getModelType(), newConstants, this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), this->getModules(), this->getActionNameToIndexMapping(), this->getRewardModels(), this->getLabels(), this->getOptionalInitialConstruct(), this->getOptionalSystemCompositionConstruct());
         }
         
         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) {
@@ -763,7 +809,10 @@ namespace storm {
                 newRewardModels.emplace_back(rewardModel.substitute(constantSubstitution));
             }
             
-            storm::prism::InitialConstruct newInitialConstruct = this->getInitialConstruct().substitute(constantSubstitution);
+            boost::optional<storm::prism::InitialConstruct> newInitialConstruct;
+            if (this->hasInitialConstruct()) {
+                newInitialConstruct = this->getInitialConstruct().substitute(constantSubstitution);
+            }
             
             std::vector<Label> newLabels;
             newLabels.reserve(this->getNumberOfLabels());
@@ -807,18 +856,22 @@ 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()) {
+                    STORM_LOG_THROW(!this->hasInitialConstruct(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": illegal to specify initial value if an initial construct is present.");
+                    
+                    // 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.
@@ -853,16 +906,20 @@ 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()) {
+                    STORM_LOG_THROW(!this->hasInitialConstruct(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": illegal to specify initial value if an initial construct is present.");
+
+                    // 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.
@@ -875,17 +932,21 @@ 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()) {
+                        STORM_LOG_THROW(!this->hasInitialConstruct(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": illegal to specify initial value if an initial construct is present.");
+
+                        // 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.
@@ -918,17 +979,21 @@ 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()) {
+                        STORM_LOG_THROW(!this->hasInitialConstruct(), storm::exceptions::WrongFormatException, "Error in " << variable.getFilename() << ", line " << variable.getLineNumber() << ": illegal to specify initial value if an initial construct is present.");
+
+                        // 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.
@@ -1091,9 +1156,11 @@ namespace storm {
             }
             
             // Check the initial states expression.
-            std::set<storm::expressions::Variable> containedIdentifiers = this->getInitialConstruct().getInitialStatesExpression().getVariables();
-            bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
-            STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << this->getInitialConstruct().getFilename() << ", line " << this->getInitialConstruct().getLineNumber() << ": initial expression refers to unknown identifiers.");
+            if (this->hasInitialConstruct()) {
+                std::set<storm::expressions::Variable> containedIdentifiers = this->getInitialConstruct().getInitialStatesExpression().getVariables();
+                bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
+                STORM_LOG_THROW(isValid, storm::exceptions::WrongFormatException, "Error in " << this->getInitialConstruct().getFilename() << ", line " << this->getInitialConstruct().getLineNumber() << ": initial construct refers to unknown identifiers.");
+            }
             
             // Check the system composition if given.
             if (systemCompositionConstruct) {
@@ -1151,17 +1218,28 @@ namespace storm {
         }
         
         Program Program::simplify() {
+            // 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 = 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()) {
+                
+                // 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.
-                
+                // 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()) {
@@ -1171,54 +1249,84 @@ 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;
-                for(auto const& variable : module.getBooleanVariables()) {
-                    if(booleanVars.count(variable.getExpressionVariable()) == 0) {
-                        newBVars.push_back(variable);
+                std::vector<storm::prism::BooleanVariable> newBooleanVars;
+                for (auto const& variable : module.getBooleanVariables()) {
+                    if (booleanVars.find(variable.getExpressionVariable()) == booleanVars.end()) {
+                        newBooleanVars.push_back(variable);
                     }
                 }
-                std::vector<storm::prism::IntegerVariable> newIVars;
-                for(auto const& variable : module.getIntegerVariables()) {
-                    if(integerVars.count(variable.getExpressionVariable()) == 0) {
-                        newIVars.push_back(variable);
+                std::vector<storm::prism::IntegerVariable> newIntegerVars;
+                for (auto const& variable : module.getIntegerVariables()) {
+                    if (integerVars.find(variable.getExpressionVariable()) == integerVars.end()) {
+                        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) {
+                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();
+            // 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);
+                    }
+                }
+            }
             
-        }
-        
-        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());
+            return Program(this->manager, modelType, newConstants, getGlobalBooleanVariables(), getGlobalIntegerVariables(), getFormulas(), newModules, actionIndicesToDelete.empty() ? getActionNameToIndexMapping() : newActionToIndexMap, actionIndicesToDelete.empty() ? this->getRewardModels() : newRewardModels, getLabels(), getOptionalInitialConstruct(), this->getOptionalSystemCompositionConstruct());
         }
         
         Program Program::flattenModules(std::unique_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) const {
@@ -1404,7 +1512,7 @@ namespace storm {
             
             // Finally, we can create the module and the program and return it.
             storm::prism::Module singleModule(newModuleName.str(), allBooleanVariables, allIntegerVariables, newCommands, this->getFilename(), 0);
-            return Program(manager, this->getModelType(), this->getConstants(), std::vector<storm::prism::BooleanVariable>(), std::vector<storm::prism::IntegerVariable>(), this->getFormulas(), {singleModule}, actionToIndexMap, this->getRewardModels(), this->getLabels(), this->getInitialConstruct(), this->getOptionalSystemCompositionConstruct(), this->getFilename(), 0, true);
+            return Program(manager, this->getModelType(), this->getConstants(), std::vector<storm::prism::BooleanVariable>(), std::vector<storm::prism::IntegerVariable>(), this->getFormulas(), {singleModule}, actionToIndexMap, this->getRewardModels(), this->getLabels(), this->getOptionalInitialConstruct(), this->getOptionalSystemCompositionConstruct(), this->getFilename(), 0, true);
         }
         
         std::unordered_map<uint_fast64_t, std::string> Program::buildCommandIndexToActionNameMap() const {
@@ -1527,7 +1635,7 @@ namespace storm {
                 default: modelType = storm::jani::ModelType::UNDEFINED;
             }
             storm::jani::Model janiModel("jani_from_prism", modelType, 1, manager);
-
+            
             // 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));
@@ -1539,12 +1647,22 @@ namespace storm {
             
             // Add all global variables of the PRISM program to the JANI model.
             for (auto const& variable : globalIntegerVariables) {
-                storm::jani::BoundedIntegerVariable const& newVariable = janiModel.addBoundedIntegerVariable(storm::jani::BoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression(), variable.getLowerBoundExpression(), variable.getUpperBoundExpression()));
-                variableToVariableMap.emplace(variable.getExpressionVariable(), newVariable);
+                if (variable.hasInitialValue()) {
+                    storm::jani::BoundedIntegerVariable const& createdVariable = janiModel.addBoundedIntegerVariable(storm::jani::BoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression(), false, variable.getLowerBoundExpression(), variable.getUpperBoundExpression()));
+                    variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
+                } else {
+                    storm::jani::BoundedIntegerVariable const& createdVariable = janiModel.addBoundedIntegerVariable(storm::jani::BoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), false, variable.getLowerBoundExpression(), variable.getUpperBoundExpression()));
+                    variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
+                }
             }
             for (auto const& variable : globalBooleanVariables) {
-                storm::jani::BooleanVariable const& newVariable = janiModel.addBooleanVariable(storm::jani::BooleanVariable(variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression()));
-                variableToVariableMap.emplace(variable.getExpressionVariable(), newVariable);
+                if (variable.hasInitialValue()) {
+                    storm::jani::BooleanVariable const& createdVariable = janiModel.addBooleanVariable(storm::jani::BooleanVariable(variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression(), false));
+                    variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
+                } else {
+                    storm::jani::BooleanVariable const& createdVariable = janiModel.addBooleanVariable(storm::jani::BooleanVariable(variable.getName(), variable.getExpressionVariable(), false));
+                    variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
+                }
             }
             
             // Add all actions of the PRISM program to the JANI model.
@@ -1556,7 +1674,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) {
@@ -1584,31 +1702,30 @@ namespace storm {
             // previously built mapping to make variables global that are read by more than one module.
             for (auto const& module : modules) {
                 storm::jani::Automaton automaton(module.getName());
-
                 for (auto const& variable : module.getIntegerVariables()) {
-                    storm::jani::BoundedIntegerVariable newIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression(), variable.getLowerBoundExpression(), variable.getUpperBoundExpression());
+                    storm::jani::BoundedIntegerVariable newIntegerVariable = *storm::jani::makeBoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.hasInitialValue() ? boost::make_optional(variable.getInitialValueExpression()) : boost::none, false, 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) {
-                        storm::jani::BoundedIntegerVariable const& newVariable = automaton.addBoundedIntegerVariable(newIntegerVariable);
-                        variableToVariableMap.emplace(variable.getExpressionVariable(), newVariable);
+                        storm::jani::BoundedIntegerVariable const& createdVariable = automaton.addBoundedIntegerVariable(newIntegerVariable);
+                        variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
                     } else if (!accessingModuleIndices.empty()) {
                         // Otherwise, we need to make it global.
-                        storm::jani::BoundedIntegerVariable const& newVariable = janiModel.addBoundedIntegerVariable(newIntegerVariable);
-                        variableToVariableMap.emplace(variable.getExpressionVariable(), newVariable);
+                        storm::jani::BoundedIntegerVariable const& createdVariable = janiModel.addBoundedIntegerVariable(newIntegerVariable);
+                        variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
                     }
                 }
                 for (auto const& variable : module.getBooleanVariables()) {
-                    storm::jani::BooleanVariable newBooleanVariable(variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression());
+                    storm::jani::BooleanVariable newBooleanVariable = *storm::jani::makeBooleanVariable(variable.getName(), variable.getExpressionVariable(), variable.hasInitialValue() ? boost::make_optional(variable.getInitialValueExpression()) : boost::none, false);
                     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) {
-                        storm::jani::BooleanVariable const& newVariable = automaton.addBooleanVariable(newBooleanVariable);
-                        variableToVariableMap.emplace(variable.getExpressionVariable(), newVariable);
+                        storm::jani::BooleanVariable const& createdVariable = automaton.addBooleanVariable(newBooleanVariable);
+                        variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
                     } else if (!accessingModuleIndices.empty()) {
                         // Otherwise, we need to make it global.
-                        storm::jani::BooleanVariable const& newVariable = janiModel.addBooleanVariable(newBooleanVariable);
-                        variableToVariableMap.emplace(variable.getExpressionVariable(), newVariable);
+                        storm::jani::BooleanVariable const& createdVariable = janiModel.addBooleanVariable(newBooleanVariable);
+                        variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
                     }
                 }
                 automaton.setInitialStatesRestriction(manager->boolean(true));
@@ -1647,7 +1764,12 @@ namespace storm {
                 
                 janiModel.addAutomaton(automaton);
             }
-            janiModel.setInitialStatesRestriction(manager->boolean(true));
+            
+            if (this->hasInitialConstruct()) {
+                janiModel.setInitialStatesRestriction(this->getInitialConstruct().getInitialStatesExpression());
+            } else {
+                janiModel.setInitialStatesRestriction(manager->boolean(true));
+            }
             
             // Set the standard system composition. This is possible, because we reject non-standard compositions anyway.
             if (this->specifiesSystemComposition()) {
@@ -1662,6 +1784,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;
@@ -1706,7 +1841,9 @@ namespace storm {
                 stream << label << std::endl;
             }
             
-            stream << program.getInitialConstruct() << std::endl;
+            if (program.hasInitialConstruct()) {
+                stream << program.getInitialConstruct() << std::endl;
+            }
             
             if (program.specifiesSystemComposition()) {
                 stream << program.getSystemCompositionConstruct();
diff --git a/src/storage/prism/Program.h b/src/storage/prism/Program.h
index 71719c583..41ef5f173 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.
              *
@@ -285,12 +285,31 @@ namespace storm {
              */
             std::map<std::string, uint_fast64_t> const& getActionNameToIndexMapping() const;
             
+            /*!
+             * Retrieves whether the program specifies an initial construct.
+             */
+            bool hasInitialConstruct() const;
+            
             /*!
              * Retrieves the initial construct of the program.
              *
              * @return The initial construct of the program.
              */
             InitialConstruct const& getInitialConstruct() const;
+
+            /*!
+             * Retrieves an optional containing the initial construct of the program if there is any and nothing otherwise.
+             *
+             * @return The initial construct of the program.
+             */
+            boost::optional<InitialConstruct> const& getOptionalInitialConstruct() const;
+
+            /*!
+             * Retrieves an expression characterizing the initial states.
+             *
+             * @return an expression characterizing the initial states.
+             */
+            storm::expressions::Expression getInitialStatesExpression() const;
             
             /*!
              * Retrieves whether the program specifies a system composition in terms of process algebra operations over
@@ -587,6 +606,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;
             
@@ -633,7 +657,7 @@ namespace storm {
             std::map<std::string, uint_fast64_t> rewardModelToIndexMap;
             
             // The initial construct of the program.
-            InitialConstruct initialConstruct;
+            boost::optional<InitialConstruct> initialConstruct;
             
             // If set, this specifies the way the modules are composed to obtain the full system.
             boost::optional<SystemCompositionConstruct> systemCompositionConstruct;
@@ -661,14 +685,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);
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/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
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) {
diff --git a/src/utility/constants.cpp b/src/utility/constants.cpp
index 71d56cd63..6d954722a 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,16 @@ namespace storm {
         	// FIXME: this should be treated more properly.
         	return storm::RationalNumber(-1);
         }
+        
+        template<>
+        bool isInteger(storm::RationalNumber const& number) {
+            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>
@@ -102,9 +128,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 +177,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 +198,31 @@ 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) {
+        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);
         }
+        
+        template<>
+        RationalNumber pow(RationalNumber const& value, uint_fast64_t exponent) {
+            return carl::pow(value, exponent);
+        }
+
 #endif
 
         template<typename IndexType, typename ValueType>
@@ -214,6 +261,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 +272,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 +289,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 +328,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);
     }
 }
 
diff --git a/src/utility/storm.cpp b/src/utility/storm.cpp
index 8ea25af28..5bc0fdfee 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;
     }
diff --git a/src/utility/storm.h b/src/utility/storm.h
index a8aa4a828..faaef184f 100644
--- a/src/utility/storm.h
+++ b/src/utility/storm.h
@@ -382,10 +382,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());
         }
diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp
index 260c4963a..5cfe7b07e 100644
--- a/test/functional/parser/PrismParserTest.cpp
+++ b/test/functional/parser/PrismParserTest.cpp
@@ -79,10 +79,6 @@ TEST(PrismParser, ComplexTest) {
     module mod3 = mod1 [ i = i1, j = j1, k = k1 ] endmodule
                                                                
     label "mal" = max(a, 10) > 0;
-                                                               
-    init
-        true
-    endinit
     
     rewards "testrewards"
         [a] true : a + 7;
diff --git a/util/osx-package/package.sh b/util/osx-package/package.sh
new file mode 100644
index 000000000..0db5b2b5d
--- /dev/null
+++ b/util/osx-package/package.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
diff --git a/util/osx-package/packager.py b/util/osx-package/packager.py
new file mode 100644
index 000000000..60b26a8b8
--- /dev/null
+++ b/util/osx-package/packager.py
@@ -0,0 +1,103 @@
+import argparse
+import subprocess
+import os
+from shutil import copyfile
+
+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 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('--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
+
+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 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 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()
+
+    #create_package(args)
+    fix_paths(args.dir, args.binary_basename)
+
+