From 01bd1fbc7669b4388ea3d0a41d017c0156f5e51f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sat, 17 Jan 2015 12:22:49 +0100
Subject: [PATCH] Model building works again for parametric systems.

Former-commit-id: d3f3e357cac3bd440485800bec96f9602e64a43e
---
 src/adapters/extendedCarl.h                   |   1 +
 src/builder/ExplicitPrismModelBuilder.cpp     |  47 ++--
 src/builder/ExplicitPrismModelBuilder.h       |  14 +-
 .../reachability/CollectConstraints.h         |   6 +-
 src/models/Dtmc.h                             |   4 +-
 .../expressions/ExpressionEvaluation.h        | 209 ------------------
 .../expressions/ExpressionEvaluator.cpp       |  36 +++
 src/storage/expressions/ExpressionEvaluator.h |  43 +++-
 .../expressions/ExpressionEvaluatorBase.cpp   |  12 +-
 .../expressions/ExpressionEvaluatorBase.h     |   3 +-
 .../expressions/ExprtkExpressionEvaluator.cpp |  51 +++--
 .../expressions/ExprtkExpressionEvaluator.h   |  39 ++--
 .../expressions/ToRationalFunctionVisitor.cpp | 102 +++++++++
 .../expressions/ToRationalFunctionVisitor.h   |  53 +++++
 src/storage/parameters.h                      |   6 +-
 src/stormParametric.cpp                       |   2 +-
 16 files changed, 339 insertions(+), 289 deletions(-)
 delete mode 100644 src/storage/expressions/ExpressionEvaluation.h
 create mode 100644 src/storage/expressions/ToRationalFunctionVisitor.cpp
 create mode 100644 src/storage/expressions/ToRationalFunctionVisitor.h

diff --git a/src/adapters/extendedCarl.h b/src/adapters/extendedCarl.h
index fddb4950f..1fb6ca9c0 100644
--- a/src/adapters/extendedCarl.h
+++ b/src/adapters/extendedCarl.h
@@ -23,6 +23,7 @@ namespace carl
         std::hash<carl::MultivariatePolynomial<C,O,P>> h;
         return h(p);
     }
+    
     template<typename Pol>
     inline size_t hash_value(carl::RationalFunction<Pol> const& f)
     {
diff --git a/src/builder/ExplicitPrismModelBuilder.cpp b/src/builder/ExplicitPrismModelBuilder.cpp
index ce88522eb..4b69e3988 100644
--- a/src/builder/ExplicitPrismModelBuilder.cpp
+++ b/src/builder/ExplicitPrismModelBuilder.cpp
@@ -61,7 +61,9 @@ namespace storm {
             std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions = storm::utility::prism::parseConstantDefinitionString(program, constantDefinitionString);
             
             storm::prism::Program preparedProgram = program.defineUndefinedConstants(constantDefinitions);
-            STORM_LOG_THROW(!preparedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
+            if (!std::is_same<ValueType, RationalFunction>::value) {
+                STORM_LOG_THROW(!preparedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
+            }
             
             // Now that we have defined all the constants in the program, we need to substitute their appearances in
             // all expressions in the program so we can then evaluate them without having to store the values of the
@@ -105,7 +107,7 @@ namespace storm {
         }
         
         template <typename ValueType, typename IndexType>
-        void ExplicitPrismModelBuilder<ValueType, IndexType>::unpackStateIntoEvaluator(storm::storage::BitVector const& currentState, VariableInformation const& variableInformation, storm::expressions::ExprtkExpressionEvaluator& evaluator) {
+        void ExplicitPrismModelBuilder<ValueType, IndexType>::unpackStateIntoEvaluator(storm::storage::BitVector const& currentState, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<ValueType>& evaluator) {
             for (auto const& booleanVariable : variableInformation.booleanVariables) {
                 evaluator.setBooleanValue(booleanVariable.variable, currentState.get(booleanVariable.bitOffset));
             }
@@ -115,12 +117,12 @@ namespace storm {
         }
         
         template <typename ValueType, typename IndexType>
-        typename ExplicitPrismModelBuilder<ValueType, IndexType>::CompressedState ExplicitPrismModelBuilder<ValueType, IndexType>::applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, storm::prism::Update const& update, storm::expressions::ExprtkExpressionEvaluator const& evaluator) {
+        typename ExplicitPrismModelBuilder<ValueType, IndexType>::CompressedState ExplicitPrismModelBuilder<ValueType, IndexType>::applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, storm::prism::Update const& update, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator) {
             return applyUpdate(variableInformation, state, state, update, evaluator);
         }
         
         template <typename ValueType, typename IndexType>
-        typename ExplicitPrismModelBuilder<ValueType, IndexType>::CompressedState ExplicitPrismModelBuilder<ValueType, IndexType>::applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, CompressedState const& baseState, storm::prism::Update const& update, storm::expressions::ExprtkExpressionEvaluator const& evaluator) {
+        typename ExplicitPrismModelBuilder<ValueType, IndexType>::CompressedState ExplicitPrismModelBuilder<ValueType, IndexType>::applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, CompressedState const& baseState, storm::prism::Update const& update, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator) {
             CompressedState newState(state);
             
             auto assignmentIt = update.getAssignments().begin();
@@ -166,7 +168,7 @@ namespace storm {
         }
         
         template <typename ValueType, typename IndexType>
-        boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> ExplicitPrismModelBuilder<ValueType, IndexType>::getActiveCommandsByActionIndex(storm::prism::Program const& program,storm::expressions::ExprtkExpressionEvaluator const& evaluator, uint_fast64_t const& actionIndex) {
+        boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> ExplicitPrismModelBuilder<ValueType, IndexType>::getActiveCommandsByActionIndex(storm::prism::Program const& program,storm::expressions::ExpressionEvaluator<ValueType> const& evaluator, 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.
@@ -209,7 +211,7 @@ namespace storm {
         }
         
         template <typename ValueType, typename IndexType>
-        std::vector<Choice<ValueType>> ExplicitPrismModelBuilder<ValueType, IndexType>::getUnlabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExprtkExpressionEvaluator const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator) {
+        std::vector<Choice<ValueType>> ExplicitPrismModelBuilder<ValueType, IndexType>::getUnlabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator) {
             std::vector<Choice<ValueType>> result;
             
             // Iterate over all modules.
@@ -237,7 +239,7 @@ namespace storm {
                     }
                     
                     // Iterate over all updates of the current command.
-                    double probabilitySum = 0;
+                    ValueType probabilitySum = storm::utility::zero<ValueType>();
                     for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) {
                         storm::prism::Update const& update = command.getUpdate(k);
                         
@@ -246,7 +248,7 @@ namespace storm {
                         uint32_t stateIndex = getOrAddStateIndex(applyUpdate(variableInformation, currentState, update, evaluator), stateInformation, stateQueue);
                         
                         // Update the choice by adding the probability/target state to it.
-                        ValueType probability = evaluator.asDouble(update.getLikelihoodExpression());
+                        ValueType probability = evaluator.asRational(update.getLikelihoodExpression());
                         choice.addProbability(stateIndex, probability);
                         probabilitySum += probability;
                     }
@@ -260,7 +262,7 @@ namespace storm {
         }
         
         template <typename ValueType, typename IndexType>
-        std::vector<Choice<ValueType>> ExplicitPrismModelBuilder<ValueType, IndexType>::getLabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExprtkExpressionEvaluator const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator) {
+        std::vector<Choice<ValueType>> ExplicitPrismModelBuilder<ValueType, IndexType>::getLabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator) {
             std::vector<Choice<ValueType>> result;
             
             for (uint_fast64_t actionIndex : program.getActionIndices()) {
@@ -294,7 +296,7 @@ namespace storm {
                                 for (auto const& stateProbabilityPair : *currentTargetStates) {
                                     // Compute the new state under the current update and add it to the set of new target states.
                                     CompressedState newTargetState = applyUpdate(variableInformation, stateProbabilityPair.first, currentState, update, evaluator);
-                                    newTargetStates->emplace(newTargetState, stateProbabilityPair.second * evaluator.asDouble(update.getLikelihoodExpression()));
+                                    newTargetStates->emplace(newTargetState, stateProbabilityPair.second * evaluator.asRational(update.getLikelihoodExpression()));
                                 }
                             }
                             
@@ -322,7 +324,7 @@ namespace storm {
                             }
                         }
                         
-                        double probabilitySum = 0;
+                        ValueType probabilitySum = storm::utility::zero<ValueType>();
                         for (auto const& stateProbabilityPair : *newTargetStates) {
                             uint32_t actualIndex = getOrAddStateIndex(stateProbabilityPair.first, stateInformation, stateQueue);
                             choice.addProbability(actualIndex, stateProbabilityPair.second);
@@ -385,12 +387,12 @@ namespace storm {
             
             // Now explore the current state until there is no more reachable state.
             uint_fast64_t currentRow = 0;
-            storm::expressions::ExprtkExpressionEvaluator evaluator(program.getManager());
+            storm::expressions::ExpressionEvaluator<ValueType> evaluator(program.getManager());
             while (!stateQueue.empty()) {
                 // Get the current state and unpack it.
                 storm::storage::BitVector currentState = stateQueue.front();
                 stateQueue.pop();
-                ValueType stateIndex = stateInformation.stateStorage.getValue(currentState);
+                IndexType stateIndex = stateInformation.stateStorage.getValue(currentState);
                 unpackStateIntoEvaluator(currentState, variableInformation, evaluator);
                 
                 // Retrieve all choices for the current state.
@@ -432,7 +434,7 @@ namespace storm {
                             // Now add all rewards that match this choice.
                             for (auto const& transitionReward : transitionRewards) {
                                 if (!transitionReward.isLabeled() && evaluator.asBool(transitionReward.getStatePredicateExpression())) {
-                                    stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asDouble(transitionReward.getRewardValueExpression()));
+                                    stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asRational(transitionReward.getRewardValueExpression()));
                                 }
                             }
                         }
@@ -443,7 +445,7 @@ namespace storm {
                             // Now add all rewards that match this choice.
                             for (auto const& transitionReward : transitionRewards) {
                                 if (transitionReward.isLabeled() && transitionReward.getActionIndex() == globalChoice.getActionIndex() && evaluator.asBool(transitionReward.getStatePredicateExpression())) {
-                                    stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asDouble(transitionReward.getRewardValueExpression()));
+                                    stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asRational(transitionReward.getRewardValueExpression()));
                                 }
                             }
                         }
@@ -486,7 +488,7 @@ namespace storm {
                                 // Now add all rewards that match this choice.
                                 for (auto const& transitionReward : transitionRewards) {
                                     if (!transitionReward.isLabeled() && evaluator.asBool(transitionReward.getStatePredicateExpression())) {
-                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asDouble(transitionReward.getRewardValueExpression()));
+                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asRational(transitionReward.getRewardValueExpression()));
                                     }
                                 }
                             }
@@ -502,7 +504,7 @@ namespace storm {
                                 // Now add all rewards that match this choice.
                                 for (auto const& transitionReward : transitionRewards) {
                                     if (transitionReward.isLabeled() && transitionReward.getActionIndex() == choice.getActionIndex() && evaluator.asBool(transitionReward.getStatePredicateExpression())) {
-                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asDouble(transitionReward.getRewardValueExpression()));
+                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asRational(transitionReward.getRewardValueExpression()));
                                     }
                                 }
                             }
@@ -544,7 +546,7 @@ namespace storm {
                                 // Now add all rewards that match this choice.
                                 for (auto const& transitionReward : transitionRewards) {
                                     if (!transitionReward.isLabeled() && evaluator.asBool(transitionReward.getStatePredicateExpression())) {
-                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asDouble(transitionReward.getRewardValueExpression()));
+                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asRational(transitionReward.getRewardValueExpression()));
                                     }
                                 }
                                 
@@ -573,7 +575,7 @@ namespace storm {
                                 // Now add all rewards that match this choice.
                                 for (auto const& transitionReward : transitionRewards) {
                                     if (transitionReward.getActionIndex() == choice.getActionIndex() && evaluator.asBool(transitionReward.getStatePredicateExpression())) {
-                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asDouble(transitionReward.getRewardValueExpression()));
+                                        stateToRewardMap[stateProbabilityPair.first] += ValueType(evaluator.asRational(transitionReward.getRewardValueExpression()));
                                     }
                                 }
                                 
@@ -659,7 +661,7 @@ namespace storm {
         
         template <typename ValueType, typename IndexType>
         storm::models::AtomicPropositionsLabeling ExplicitPrismModelBuilder<ValueType, IndexType>::buildStateLabeling(storm::prism::Program const& program, VariableInformation const& variableInformation, StateInformation const& stateInformation) {
-            storm::expressions::ExprtkExpressionEvaluator evaluator(program.getManager());
+            storm::expressions::ExpressionEvaluator<ValueType> evaluator(program.getManager());
             
             std::vector<storm::prism::Label> const& labels = program.getLabels();
             
@@ -690,7 +692,7 @@ namespace storm {
         
         template <typename ValueType, typename IndexType>
         std::vector<ValueType> ExplicitPrismModelBuilder<ValueType, IndexType>::buildStateRewards(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<storm::prism::StateReward> const& rewards, StateInformation const& stateInformation) {
-            storm::expressions::ExprtkExpressionEvaluator evaluator(program.getManager());
+            storm::expressions::ExpressionEvaluator<ValueType> evaluator(program.getManager());
             
             std::vector<ValueType> result(stateInformation.reachableStates.size());
             for (uint_fast64_t index = 0; index < stateInformation.reachableStates.size(); index++) {
@@ -700,7 +702,7 @@ namespace storm {
                     
                     // Add this reward to the state if the state is included in the state reward.
                     if (evaluator.asBool(reward.getStatePredicateExpression())) {
-                        result[index] += ValueType(evaluator.asDouble(reward.getRewardValueExpression()));
+                        result[index] += ValueType(evaluator.asRational(reward.getRewardValueExpression()));
                     }
                 }
             }
@@ -709,5 +711,6 @@ namespace storm {
         
         // Explicitly instantiate the class.
         template class ExplicitPrismModelBuilder<double, uint32_t>;
+        template class ExplicitPrismModelBuilder<RationalFunction, uint32_t>;
     }
 }
\ No newline at end of file
diff --git a/src/builder/ExplicitPrismModelBuilder.h b/src/builder/ExplicitPrismModelBuilder.h
index ee35e4108..9b024ea04 100644
--- a/src/builder/ExplicitPrismModelBuilder.h
+++ b/src/builder/ExplicitPrismModelBuilder.h
@@ -12,7 +12,7 @@
 
 #include "src/storage/prism/Program.h"
 #include "src/storage/expressions/SimpleValuation.h"
-#include "src/storage/expressions/ExprtkExpressionEvaluator.h"
+#include "src/storage/expressions/ExpressionEvaluator.h"
 #include "src/storage/BitVectorHashMap.h"
 #include "src/models/AbstractModel.h"
 #include "src/models/AtomicPropositionsLabeling.h"
@@ -132,7 +132,7 @@ namespace storm {
             static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::prism::Program program, bool commandLabels = false, bool rewards = true, std::string const& rewardModelName = "", std::string const& constantDefinitionString = "");
             
         private:
-            static void unpackStateIntoEvaluator(storm::storage::BitVector const& currentState, VariableInformation const& variableInformation, storm::expressions::ExprtkExpressionEvaluator& evaluator);
+            static void unpackStateIntoEvaluator(storm::storage::BitVector const& currentState, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<ValueType>& evaluator);
             
             /*!
              * Applies an update to the given state and returns the resulting new state object. This methods does not
@@ -142,7 +142,7 @@ namespace storm {
              * @params update The update to apply.
              * @return The resulting state.
              */
-            static CompressedState applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, storm::prism::Update const& update, storm::expressions::ExprtkExpressionEvaluator const& evaluator);
+            static CompressedState applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, storm::prism::Update const& update, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator);
             
             /*!
              * Applies an update to the given state and returns the resulting new state object. The update is evaluated
@@ -154,7 +154,7 @@ namespace storm {
              * @param update The update to apply.
              * @return The resulting state.
              */
-            static CompressedState applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, CompressedState const& baseState, storm::prism::Update const& update, storm::expressions::ExprtkExpressionEvaluator const& evaluator);
+            static CompressedState applyUpdate(VariableInformation const& variableInformation, CompressedState const& state, CompressedState const& baseState, storm::prism::Update const& update, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator);
             
             /*!
              * Retrieves the state id of the given state. If the state has not been encountered yet, it will be added to
@@ -184,11 +184,11 @@ namespace storm {
              * @param actionIndex The index of the action label to select.
              * @return A list of lists of active commands or nothing.
              */
-            static boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> getActiveCommandsByActionIndex(storm::prism::Program const& program,storm::expressions::ExprtkExpressionEvaluator const& evaluator, uint_fast64_t const& actionIndex);
+            static boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> getActiveCommandsByActionIndex(storm::prism::Program const& program,storm::expressions::ExpressionEvaluator<ValueType> const& evaluator, uint_fast64_t const& actionIndex);
                         
-            static std::vector<Choice<ValueType>> getUnlabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExprtkExpressionEvaluator const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator);
+            static std::vector<Choice<ValueType>> getUnlabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator);
             
-            static std::vector<Choice<ValueType>> getLabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExprtkExpressionEvaluator const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator);
+            static std::vector<Choice<ValueType>> getLabeledTransitions(storm::prism::Program const& program, bool discreteTimeModel, StateInformation& stateInformation, VariableInformation const& variableInformation, storm::storage::BitVector const& currentState, bool choiceLabeling, storm::expressions::ExpressionEvaluator<ValueType> const& evaluator, std::queue<storm::storage::BitVector>& stateQueue, storm::utility::ConstantsComparator<ValueType> const& comparator);
             /*!
              * Builds the transition matrix and the transition reward matrix based for the given program.
              *
diff --git a/src/modelchecker/reachability/CollectConstraints.h b/src/modelchecker/reachability/CollectConstraints.h
index cd7fa90f3..d77273770 100644
--- a/src/modelchecker/reachability/CollectConstraints.h
+++ b/src/modelchecker/reachability/CollectConstraints.h
@@ -8,7 +8,6 @@
 #pragma once
 #include "src/models/Dtmc.h"
 
-
 namespace storm {
 namespace modelchecker {
 	namespace reachability {
@@ -18,6 +17,7 @@ namespace modelchecker {
 			private:
 				std::unordered_set<carl::Constraint<ValueType>> wellformedConstraintSet;
 				std::unordered_set<carl::Constraint<ValueType>> graphPreservingConstraintSet;
+            storm::utility::ConstantsComparator<ValueType> comparator;
 
 			public:
 				std::unordered_set<carl::Constraint<ValueType>> const&  wellformedConstraints() const {
@@ -33,7 +33,7 @@ namespace modelchecker {
 					for(uint_fast64_t state = 0; state < dtmc.getNumberOfStates(); ++state)
 					{
 						ValueType sum;
-						assert(storm::utility::isZero(sum));
+						assert(comparator.isZero(sum));
 						for(auto const& transition : dtmc.getRows(state))
 						{
 							sum += transition.getValue();
@@ -44,7 +44,7 @@ namespace modelchecker {
 								graphPreservingConstraintSet.emplace(transition.getValue(), storm::CompareRelation::GT);
 							}
 						}
-						assert(!sum.isConstant() || storm::utility::isOne(sum));
+						assert(!comparator.isConstant(sum) || comparator.isOne(sum));
 						if(!sum.isConstant()) {
 							wellformedConstraintSet.emplace(sum - 1, storm::CompareRelation::EQ);
 						}
diff --git a/src/models/Dtmc.h b/src/models/Dtmc.h
index 8c082690f..1eaa9e138 100644
--- a/src/models/Dtmc.h
+++ b/src/models/Dtmc.h
@@ -354,9 +354,7 @@ private:
 		}
 		return true;
 	}
-	
-	
-	
+
 	
 };
 
diff --git a/src/storage/expressions/ExpressionEvaluation.h b/src/storage/expressions/ExpressionEvaluation.h
deleted file mode 100644
index 89a32b038..000000000
--- a/src/storage/expressions/ExpressionEvaluation.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * @file:   ExpressionEvaluation.h
- * @author: Sebastian Junges
- *
- * @since April 4, 2014
- */
-
-#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATION_H_
-#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATION_H_
-
-#include "ExpressionVisitor.h"
-#include "BaseExpression.h"
-#include "IfThenElseExpression.h"
-#include "DoubleLiteralExpression.h"
-#include "BinaryNumericalFunctionExpression.h"
-
-#include "src/storage/parameters.h"
-#include "IntegerLiteralExpression.h"
-#include "BinaryExpression.h"
-#include "src/storage/parameters.h"
-
-namespace storm {
-    namespace expressions {
-        
-        template<typename T>
-        struct StateType
-        {
-            typedef int type;
-        };
-        
-#ifdef PARAMETRIC_SYSTEMS
-        template<>
-        struct StateType<Polynomial>
-        {
-            typedef std::map<std::string, carl::Variable> type;
-        };
-        
-        template<>
-        struct StateType<RationalFunction>
-        {
-            typedef std::map<std::string, carl::Variable> type;
-        };
-#endif
-		
-        template<typename T, typename S>
-        class ExpressionEvaluationVisitor : public ExpressionVisitor
-        {
-		public:
-			ExpressionEvaluationVisitor(S* sharedState)
-			: mSharedState(sharedState), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>())
-			{
-
-			}
-            
-            ExpressionEvaluationVisitor(S* sharedState, std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache)
-            : mSharedState(sharedState), cache(cache)
-            {
-
-            }
-            
-            
-			virtual ~ExpressionEvaluationVisitor() {
-                
-            }
-			
-			virtual void visit(IfThenElseExpression const* expression)
-			{
-				std::cout << "ite" << std::endl;
-				
-			}
-            
-            virtual void visit(BinaryBooleanFunctionExpression const* expression)
-			{
-				std::cout << "bbf" << std::endl;
-			}
-            virtual void visit(BinaryNumericalFunctionExpression const* expression)
-			{
-				ExpressionEvaluationVisitor* visitor = new ExpressionEvaluationVisitor(mSharedState, this->cache);
-				expression->getFirstOperand()->accept(visitor);
-				mValue = visitor->value();
-				expression->getSecondOperand()->accept(visitor);
-				switch(expression->getOperatorType())
-				{
-					case BinaryNumericalFunctionExpression::OperatorType::Plus:
-						mValue += visitor->value();
-						break;
-					case BinaryNumericalFunctionExpression::OperatorType::Minus:
-						mValue -= visitor->value();
-						break;
-					case BinaryNumericalFunctionExpression::OperatorType::Times:
-						mValue *= visitor->value();
-						break;
-					case BinaryNumericalFunctionExpression::OperatorType::Divide:
-						mValue /= visitor->value();
-						break;
-					default:
-						// TODO exception.
-						assert(false);
-				}
-				
-				delete visitor;
-			}
-            virtual void visit(BinaryRelationExpression const* expression)
-			{
-				std::cout << "br" << std::endl;
-			}
-            virtual void visit(VariableExpression const* expression)
-			{
-                std::string const& varName= expression->getVariableName();
-				auto it =  mSharedState->find(varName);
-				if(it != mSharedState->end())
-				{
-                    mValue = convertVariableToPolynomial(it->second);
-//                    mValue = T(typename T::PolyType(typename T::PolyType::PolyType(it->second), cache));
-				}
-				else
-				{
-					carl::Variable nVar = carl::VariablePool::getInstance().getFreshVariable(varName);
-					mSharedState->emplace(varName,nVar);
-                    mValue = convertVariableToPolynomial(nVar);
-				}
-			}
-            virtual void visit(UnaryBooleanFunctionExpression const* expression)
-			{
-				std::cout << "ubf" << std::endl;
-			}
-            virtual void visit(UnaryNumericalFunctionExpression const* expression)
-			{
-				std::cout << "unf" << std::endl;
-			}
-            virtual void visit(BooleanLiteralExpression const* expression)
-			{
-				std::cout << "bl" << std::endl;
-			}
-            virtual void visit(IntegerLiteralExpression const* expression)
-			{
-                mValue = T(typename T::PolyType(typename T::CoeffType(expression->getValue())));
-			}
-            virtual void visit(DoubleLiteralExpression const* expression)
-			{
-				std::stringstream str;
-				str << std::fixed << std::setprecision( 3 ) << expression->getValue();
-                mValue = T(carl::rationalize<cln::cl_RA>(str.str()));
-			}
-            
-            template<typename TP = typename T::PolyType, carl::EnableIf<carl::needs_cache<TP>> = carl::dummy>
-            T convertVariableToPolynomial(carl::Variable const& nVar) {
-                return T(typename T::PolyType(typename T::PolyType::PolyType(nVar), cache));
-            }
-            
-            template<typename TP = typename T::PolyType, carl::DisableIf<carl::needs_cache<TP>> = carl::dummy>
-            T convertVariableToPolynomial(carl::Variable const& nVar) {
-                return T(nVar);
-            }
-            
-            const T& value() const
-            {
-                return mValue;
-            }
-            
-		private:
-            S* mSharedState;
-            T mValue;
-            std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache;
-        };
-        
-        template<typename T>
-        class ExpressionEvaluation
-        {
-		public:
-            ExpressionEvaluation() : mState(), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>(100000))
-            {
-                // Intentionally left empty.
-            }
-            
-            
-            T evaluate(Expression const& expr, storm::expressions::SimpleValuation const* val)
-            {
-                ExpressionEvaluationVisitor<T, typename StateType<T>::type>* visitor = new ExpressionEvaluationVisitor<T, typename StateType<T>::type>(&mState, cache);
-                Expression expressionToTranslate = expr.substitute(*val);
-                expressionToTranslate.getBaseExpression().accept(visitor);
-                T result = visitor->value();
-                //			result.simplify();
-                delete visitor;
-                return result;
-            }
-            
-		protected:
-			typename StateType<T>::type mState;
-            std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache;
-        };
-        
-        /**
-         * For doubles, we keep using the getValueAs from the expressions, as this should be more efficient.
-         */
-        template<>
-        class ExpressionEvaluation<double>
-        {
-		public:
-            double evaluate(Expression const& expr, storm::expressions::SimpleValuation const* val) const
-            {
-                return expr.evaluateAsDouble(val);
-            }
-        };
-        
-    }
-}
-
-#endif
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionEvaluator.cpp b/src/storage/expressions/ExpressionEvaluator.cpp
index e69de29bb..cf927a0ff 100644
--- a/src/storage/expressions/ExpressionEvaluator.cpp
+++ b/src/storage/expressions/ExpressionEvaluator.cpp
@@ -0,0 +1,36 @@
+#include "src/storage/expressions/ExpressionEvaluator.h"
+#include "src/storage/expressions/ExpressionManager.h"
+
+namespace storm {
+    namespace expressions {
+        ExpressionEvaluator<double>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluator(manager) {
+            // Intentionally left empty.
+        }
+        
+#ifdef PARAMETRIC_SYSTEMS
+        ExpressionEvaluator<RationalFunction>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluatorBase<RationalFunction>(manager) {
+            // Intentionally left empty.
+        }
+        
+        void ExpressionEvaluator<RationalFunction>::setBooleanValue(storm::expressions::Variable const& variable, bool value) {
+            ExprtkExpressionEvaluatorBase::setBooleanValue(variable, value);
+            this->variableToExpressionMap[variable] = this->getManager().boolean(value);
+        }
+        
+        void ExpressionEvaluator<RationalFunction>::setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) {
+            ExprtkExpressionEvaluatorBase::setIntegerValue(variable, value);
+            this->variableToExpressionMap[variable] = this->getManager().integer(value);
+        }
+        
+        void ExpressionEvaluator<RationalFunction>::setRationalValue(storm::expressions::Variable const& variable, double value) {
+            ExprtkExpressionEvaluatorBase::setRationalValue(variable, value);
+            this->variableToExpressionMap[variable] = this->getManager().rational(value);
+        }
+        
+        RationalFunction ExpressionEvaluator<RationalFunction>::asRational(Expression const& expression) const {
+            Expression substitutedExpression = expression.substitute(variableToExpressionMap);
+            return this->rationalFunctionVisitor.toRationalFunction(substitutedExpression);
+        }
+#endif
+    }
+}
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionEvaluator.h b/src/storage/expressions/ExpressionEvaluator.h
index 5291029c4..5229807f0 100644
--- a/src/storage/expressions/ExpressionEvaluator.h
+++ b/src/storage/expressions/ExpressionEvaluator.h
@@ -1,11 +1,46 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATOR_H_
+#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATOR_H_
+
+#include <unordered_map>
+
+#include "src/storage/parameters.h"
+#include "src/storage/expressions/Variable.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/ExprtkExpressionEvaluator.h"
+#include "src/storage/expressions/ToRationalFunctionVisitor.h"
+
 namespace storm {
     namespace expressions {
-        template<RationalType>
+        template<typename RationalType>
         class ExpressionEvaluator;
         
         template<>
-        class ExpressionEvaluator<double> {
+        class ExpressionEvaluator<double> : public ExprtkExpressionEvaluator  {
+        public:
+            ExpressionEvaluator(storm::expressions::ExpressionManager const& manager);
+        };
+        
+#ifdef STORM_HAVE_CARL
+        template<>
+        class ExpressionEvaluator<RationalFunction> : public ExprtkExpressionEvaluatorBase<RationalFunction> {
+        public:
+            ExpressionEvaluator(storm::expressions::ExpressionManager const& manager);
+            
+            void setBooleanValue(storm::expressions::Variable const& variable, bool value) override;
+            void setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) override;
+            void setRationalValue(storm::expressions::Variable const& variable, double value) override;
+            
+            RationalFunction asRational(Expression const& expression) const override;
+            
+        private:
+            // A mapping of variables to their expressions.
+            std::unordered_map<storm::expressions::Variable, storm::expressions::Expression> variableToExpressionMap;
             
-        }
+            // A visitor that can be used to translate expressions to rational functions.
+            mutable ToRationalFunctionVisitor<RationalFunction> rationalFunctionVisitor;
+        };
+#endif
     }
-}
\ No newline at end of file
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATOR_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionEvaluatorBase.cpp b/src/storage/expressions/ExpressionEvaluatorBase.cpp
index 1eb76b10b..a750946e3 100644
--- a/src/storage/expressions/ExpressionEvaluatorBase.cpp
+++ b/src/storage/expressions/ExpressionEvaluatorBase.cpp
@@ -1,15 +1,23 @@
 #include "src/storage/expressions/ExpressionEvaluatorBase.h"
 
 #include "src/storage/expressions/ExpressionManager.h"
+#include "src/storage/parameters.h"
 
 namespace storm {
     namespace expressions {
-        ExpressionEvaluatorBase::ExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager) : manager(manager.getSharedPointer()) {
+        template<typename RationalType>
+        ExpressionEvaluatorBase<RationalType>::ExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager) : manager(manager.getSharedPointer()) {
             // Intentionally left empty.
         }
         
-        storm::expressions::ExpressionManager const& ExpressionEvaluatorBase::getManager() const {
+        template<typename RationalType>
+        storm::expressions::ExpressionManager const& ExpressionEvaluatorBase<RationalType>::getManager() const {
             return *manager;
         }
+        
+        template class ExpressionEvaluatorBase<double>;
+#ifdef STORM_HAVE_CARL
+        template class ExpressionEvaluatorBase<RationalFunction>;
+#endif
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/ExpressionEvaluatorBase.h b/src/storage/expressions/ExpressionEvaluatorBase.h
index 53a848611..b88c1aae7 100644
--- a/src/storage/expressions/ExpressionEvaluatorBase.h
+++ b/src/storage/expressions/ExpressionEvaluatorBase.h
@@ -5,13 +5,14 @@
 
 namespace storm {
     namespace expressions {
+        template<typename RationalReturnType>
         class ExpressionEvaluatorBase {
         public:
             ExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager);
             
             virtual bool asBool(Expression const& expression) const = 0;
             virtual int_fast64_t asInt(Expression const& expression) const = 0;
-            virtual double asDouble(Expression const& expression) const = 0;
+            virtual RationalReturnType asRational(Expression const& expression) const = 0;
             
             virtual void setBooleanValue(storm::expressions::Variable const& variable, bool value) = 0;
             virtual void setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) = 0;
diff --git a/src/storage/expressions/ExprtkExpressionEvaluator.cpp b/src/storage/expressions/ExprtkExpressionEvaluator.cpp
index 58d6176d3..11799faa5 100644
--- a/src/storage/expressions/ExprtkExpressionEvaluator.cpp
+++ b/src/storage/expressions/ExprtkExpressionEvaluator.cpp
@@ -1,11 +1,13 @@
 #include "src/storage/expressions/ExprtkExpressionEvaluator.h"
 #include "src/storage/expressions/ExpressionManager.h"
 
+#include "src/storage/parameters.h"
 #include "src/utility/macros.h"
 
 namespace storm {
     namespace expressions {
-        ExprtkExpressionEvaluator::ExprtkExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExpressionEvaluatorBase(manager), booleanValues(manager.getNumberOfBooleanVariables()), integerValues(manager.getNumberOfIntegerVariables()), rationalValues(manager.getNumberOfRationalVariables()) {
+        template<typename RationalType>
+        ExprtkExpressionEvaluatorBase<RationalType>::ExprtkExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager) : ExpressionEvaluatorBase<RationalType>(manager), booleanValues(manager.getNumberOfBooleanVariables()), integerValues(manager.getNumberOfIntegerVariables()), rationalValues(manager.getNumberOfRationalVariables()) {
 
             for (auto const& variableTypePair : manager) {
                 if (variableTypePair.second.isBooleanType()) {
@@ -19,7 +21,8 @@ namespace storm {
             symbolTable.add_constants();
         }
         
-        bool ExprtkExpressionEvaluator::asBool(Expression const& expression) const {
+        template<typename RationalType>
+        bool ExprtkExpressionEvaluatorBase<RationalType>::asBool(Expression const& expression) const {
             BaseExpression const* expressionPtr = expression.getBaseExpressionPointer().get();
             auto const& expressionPair = this->compiledExpressions.find(expression.getBaseExpressionPointer().get());
             if (expressionPair == this->compiledExpressions.end()) {
@@ -29,7 +32,8 @@ namespace storm {
             return expressionPair->second.value() == ValueType(1);
         }
         
-        int_fast64_t ExprtkExpressionEvaluator::asInt(Expression const& expression) const {
+        template<typename RationalType>
+        int_fast64_t ExprtkExpressionEvaluatorBase<RationalType>::asInt(Expression const& expression) const {
             BaseExpression const* expressionPtr = expression.getBaseExpressionPointer().get();
             auto const& expressionPair = this->compiledExpressions.find(expression.getBaseExpressionPointer().get());
             if (expressionPair == this->compiledExpressions.end()) {
@@ -39,17 +43,8 @@ namespace storm {
             return static_cast<int_fast64_t>(expressionPair->second.value());
         }
         
-        double ExprtkExpressionEvaluator::asDouble(Expression const& expression) const {
-            BaseExpression const* expressionPtr = expression.getBaseExpressionPointer().get();
-            auto const& expressionPair = this->compiledExpressions.find(expression.getBaseExpressionPointer().get());
-            if (expressionPair == this->compiledExpressions.end()) {
-                CompiledExpressionType const& compiledExpression = this->getCompiledExpression(expressionPtr);
-                return static_cast<double>(compiledExpression.value());
-            }
-            return static_cast<double>(expressionPair->second.value());
-        }
-        
-        ExprtkExpressionEvaluator::CompiledExpressionType& ExprtkExpressionEvaluator::getCompiledExpression(BaseExpression const* expression) const {
+        template<typename RationalType>
+        typename ExprtkExpressionEvaluatorBase<RationalType>::CompiledExpressionType& ExprtkExpressionEvaluatorBase<RationalType>::getCompiledExpression(BaseExpression const* expression) const {
             std::pair<CacheType::iterator, bool> result = this->compiledExpressions.emplace(expression, CompiledExpressionType());
             CompiledExpressionType& compiledExpression = result.first->second;
             compiledExpression.register_symbol_table(symbolTable);
@@ -58,16 +53,38 @@ namespace storm {
             return compiledExpression;
         }
         
-        void ExprtkExpressionEvaluator::setBooleanValue(storm::expressions::Variable const& variable, bool value) {
+        template<typename RationalType>
+        void ExprtkExpressionEvaluatorBase<RationalType>::setBooleanValue(storm::expressions::Variable const& variable, bool value) {
             this->booleanValues[variable.getOffset()] = static_cast<ValueType>(value);
         }
         
-        void ExprtkExpressionEvaluator::setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) {
+        template<typename RationalType>
+        void ExprtkExpressionEvaluatorBase<RationalType>::setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) {
             this->integerValues[variable.getOffset()] = static_cast<ValueType>(value);
         }
         
-        void ExprtkExpressionEvaluator::setRationalValue(storm::expressions::Variable const& variable, double value) {
+        template<typename RationalType>
+        void ExprtkExpressionEvaluatorBase<RationalType>::setRationalValue(storm::expressions::Variable const& variable, double value) {
             this->rationalValues[variable.getOffset()] = static_cast<ValueType>(value);
         }
+        
+        ExprtkExpressionEvaluator::ExprtkExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluatorBase<double>(manager) {
+            // Intentionally left empty.
+        }
+        
+        double ExprtkExpressionEvaluator::asRational(Expression const& expression) const {
+            BaseExpression const* expressionPtr = expression.getBaseExpressionPointer().get();
+            auto const& expressionPair = this->compiledExpressions.find(expression.getBaseExpressionPointer().get());
+            if (expressionPair == this->compiledExpressions.end()) {
+                CompiledExpressionType const& compiledExpression = this->getCompiledExpression(expressionPtr);
+                return static_cast<double>(compiledExpression.value());
+            }
+            return static_cast<double>(expressionPair->second.value());
+        }
+        
+        template class ExprtkExpressionEvaluatorBase<double>;
+#ifdef STORM_HAVE_CARL
+        template class ExprtkExpressionEvaluatorBase<RationalFunction>;
+#endif
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/ExprtkExpressionEvaluator.h b/src/storage/expressions/ExprtkExpressionEvaluator.h
index c84276ef2..9377f3522 100644
--- a/src/storage/expressions/ExprtkExpressionEvaluator.h
+++ b/src/storage/expressions/ExprtkExpressionEvaluator.h
@@ -11,24 +11,19 @@
 
 namespace storm {
     namespace expressions {
-        class ExprtkExpressionEvaluator : public ExpressionEvaluatorBase {
+        template <typename RationalType>
+        class ExprtkExpressionEvaluatorBase : public ExpressionEvaluatorBase<RationalType> {
         public:
-            /*!
-             * Creates an expression evaluator that is capable of evaluating expressions managed by the given manager.
-             *
-             * @param manager The manager responsible for the expressions.
-             */
-            ExprtkExpressionEvaluator(storm::expressions::ExpressionManager const& manager);
+            ExprtkExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager);
             
-            bool asBool(Expression const& expression) const;
-            int_fast64_t asInt(Expression const& expression) const;
-            double asDouble(Expression const& expression) const;
-
-            void setBooleanValue(storm::expressions::Variable const& variable, bool value);
-            void setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value);
-            void setRationalValue(storm::expressions::Variable const& variable, double value);
+            bool asBool(Expression const& expression) const override;
+            int_fast64_t asInt(Expression const& expression) const override;
             
-        private:
+            void setBooleanValue(storm::expressions::Variable const& variable, bool value) override;
+            void setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) override;
+            void setRationalValue(storm::expressions::Variable const& variable, double value) override;
+
+        protected:
             typedef double ValueType;
             typedef exprtk::expression<ValueType> CompiledExpressionType;
             typedef std::unordered_map<BaseExpression const*, CompiledExpressionType> CacheType;
@@ -39,7 +34,7 @@ namespace storm {
              * @param expression The expression that is to be compiled.
              */
             CompiledExpressionType& getCompiledExpression(BaseExpression const* expression) const;
-                        
+            
             // The parser used.
             mutable exprtk::parser<ValueType> parser;
             
@@ -54,6 +49,18 @@ namespace storm {
             // A mapping of expressions to their compiled counterpart.
             mutable CacheType compiledExpressions;
         };
+        
+        class ExprtkExpressionEvaluator : public ExprtkExpressionEvaluatorBase<double> {
+        public:
+            /*!
+             * Creates an expression evaluator that is capable of evaluating expressions managed by the given manager.
+             *
+             * @param manager The manager responsible for the expressions.
+             */
+            ExprtkExpressionEvaluator(storm::expressions::ExpressionManager const& manager);
+            
+            double asRational(Expression const& expression) const override;
+        };
     }
 }
 
diff --git a/src/storage/expressions/ToRationalFunctionVisitor.cpp b/src/storage/expressions/ToRationalFunctionVisitor.cpp
new file mode 100644
index 000000000..4e6516095
--- /dev/null
+++ b/src/storage/expressions/ToRationalFunctionVisitor.cpp
@@ -0,0 +1,102 @@
+#include "src/storage/expressions/ToRationalFunctionVisitor.h"
+
+#include <sstream>
+
+#include "src/utility/macros.h"
+
+#ifdef STORM_HAVE_CARL
+
+namespace storm {
+    namespace expressions {
+        template<typename RationalFunctionType>
+        ToRationalFunctionVisitor<RationalFunctionType>::ToRationalFunctionVisitor() : ExpressionVisitor(), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>()) {
+            // Intentionally left empty.
+        }
+        
+        template<typename RationalFunctionType>
+        RationalFunctionType ToRationalFunctionVisitor<RationalFunctionType>::toRationalFunction(Expression const& expression) {
+            return boost::any_cast<RationalFunctionType>(expression.accept(*this));
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IfThenElseExpression const& expression) {
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryBooleanFunctionExpression const& expression) {
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
+        }
+        
+        template<typename RationalFunctionType>
+        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));
+            switch(expression.getOperatorType()) {
+                case BinaryNumericalFunctionExpression::OperatorType::Plus:
+                    return firstOperandAsRationalFunction + secondOperandAsRationalFunction;
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Minus:
+                    return firstOperandAsRationalFunction - secondOperandAsRationalFunction;
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Times:
+                    return firstOperandAsRationalFunction * secondOperandAsRationalFunction;
+                    break;
+                case BinaryNumericalFunctionExpression::OperatorType::Divide:
+                    return firstOperandAsRationalFunction / secondOperandAsRationalFunction;
+                    break;
+                default:
+                    STORM_LOG_ASSERT(false, "Illegal operator type.");
+            }
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryRelationExpression const& expression) {
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(VariableExpression const& expression) {
+            auto variablePair = variableToVariableMap.find(expression.getVariable());
+            if (variablePair != variableToVariableMap.end()) {
+                return convertVariableToPolynomial(variablePair->second);
+            } else {
+                carl::Variable carlVariable = carl::VariablePool::getInstance().getFreshVariable(expression.getVariableName());
+                variableToVariableMap.emplace(expression.getVariable(), carlVariable);
+                return convertVariableToPolynomial(carlVariable);
+            }
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryBooleanFunctionExpression const& expression) {
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryNumericalFunctionExpression const& expression) {
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BooleanLiteralExpression const& expression) {
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IntegerLiteralExpression const& expression) {
+            return RationalFunctionType(typename RationalFunctionType::PolyType(typename RationalFunctionType::CoeffType(expression.getValue())));
+        }
+        
+        template<typename RationalFunctionType>
+        boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(DoubleLiteralExpression const& expression) {
+            std::stringstream str;
+            str << std::fixed << std::setprecision(3) << expression.getValue();
+            return RationalFunctionType(carl::rationalize<cln::cl_RA>(str.str()));
+        }
+
+        template class ToRationalFunctionVisitor<storm::RationalFunction>;
+        
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/storage/expressions/ToRationalFunctionVisitor.h b/src/storage/expressions/ToRationalFunctionVisitor.h
new file mode 100644
index 000000000..51cc96761
--- /dev/null
+++ b/src/storage/expressions/ToRationalFunctionVisitor.h
@@ -0,0 +1,53 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_
+
+#include "src/storage/parameters.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/Expressions.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+#include "src/storage/expressions/Variable.h"
+
+#ifdef STORM_HAVE_CARL
+namespace storm {
+    namespace expressions {
+
+        template<typename RationalFunctionType>
+        class ToRationalFunctionVisitor : public ExpressionVisitor {
+        public:
+            ToRationalFunctionVisitor();
+            
+            RationalFunctionType toRationalFunction(Expression const& expression);
+            
+            virtual boost::any visit(IfThenElseExpression const& expression) override;
+            virtual boost::any visit(BinaryBooleanFunctionExpression const& expression) override;
+            virtual boost::any visit(BinaryNumericalFunctionExpression const& expression) override;
+            virtual boost::any visit(BinaryRelationExpression const& expression) override;
+            virtual boost::any visit(VariableExpression const& expression) override;
+            virtual boost::any visit(UnaryBooleanFunctionExpression const& expression) override;
+            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;
+            
+        private:
+            template<typename TP = typename RationalFunctionType::PolyType, carl::EnableIf<carl::needs_cache<TP>> = carl::dummy>
+            RationalFunctionType convertVariableToPolynomial(carl::Variable const& variable) {
+                return RationalFunctionType(typename RationalFunctionType::PolyType(typename RationalFunctionType::PolyType::PolyType(variable), cache));
+            }
+            
+            template<typename TP = typename RationalFunctionType::PolyType, carl::DisableIf<carl::needs_cache<TP>> = carl::dummy>
+            RationalFunctionType convertVariableToPolynomial(carl::Variable const& variable) {
+                return RationalFunctionType(variable);
+            }
+            
+            // A mapping from our variables to carl's.
+            std::unordered_map<storm::expressions::Variable, carl::Variable> variableToVariableMap;
+            
+            // The cache that is used in case the underlying type needs a cache.
+            std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache;
+        };
+    }
+}
+#endif
+
+#endif /* STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_ */
\ No newline at end of file
diff --git a/src/storage/parameters.h b/src/storage/parameters.h
index c9eb066f7..7455690d2 100644
--- a/src/storage/parameters.h
+++ b/src/storage/parameters.h
@@ -2,13 +2,11 @@
 #define STORM_STORAGE_PARAMETERS_H_
 
 #include "storm-config.h"
-#ifdef STORM_HAVE_CARL
 
+#ifdef STORM_HAVE_CARL
 #include "../adapters/extendedCarl.h"
 
-namespace storm
-{
-//	typedef carl::MultivariatePolynomial<cln::cl_RA> Polynomial;
+namespace storm {
 	typedef carl::Variable  Variable;
     typedef carl::MultivariatePolynomial<cln::cl_RA> RawPolynomial;
     typedef carl::FactorizedPolynomial<RawPolynomial> Polynomial;
diff --git a/src/stormParametric.cpp b/src/stormParametric.cpp
index 20a32cda1..3517b95c6 100644
--- a/src/stormParametric.cpp
+++ b/src/stormParametric.cpp
@@ -143,7 +143,7 @@ int main(const int argc, const char** argv) {
         std::string const& programFile = storm::settings::generalSettings().getSymbolicModelFilename();
         std::string const& constants = storm::settings::generalSettings().getConstantDefinitionString();
         storm::prism::Program program = storm::parser::PrismParser::parse(programFile);
-        std::shared_ptr<storm::models::AbstractModel<storm::RationalFunction>> model = storm::adapters::ExplicitModelAdapter<storm::RationalFunction>::translateProgram(program, true, storm::settings::generalSettings().isSymbolicRewardModelNameSet() ? storm::settings::generalSettings().getSymbolicRewardModelName() : "", constants);
+        std::shared_ptr<storm::models::AbstractModel<storm::RationalFunction>> model = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>::translateProgram(program, true, false, storm::settings::generalSettings().isSymbolicRewardModelNameSet() ? storm::settings::generalSettings().getSymbolicRewardModelName() : "", constants);
         
         model->printModelInformationToStream(std::cout);