From b772c92edb01257ae6e601ef5e238f442972d1d3 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 16 Feb 2016 17:44:27 +0100
Subject: [PATCH 01/23] removed reward path formulas. reward path formulas are
 now just path formulas. this allows some invalid formulas to be constructed,
 so this now has to be checked dynamically

Former-commit-id: c8527c8e9ab6a78c80f3fd655c2af24c4b64407a
---
 src/logic/BoundedUntilFormula.cpp             |  4 +
 src/logic/BoundedUntilFormula.h               |  1 +
 src/logic/ConditionalPathFormula.cpp          |  4 +
 src/logic/ConditionalPathFormula.h            |  3 +-
 src/logic/CumulativeRewardFormula.cpp         |  4 +
 src/logic/CumulativeRewardFormula.h           |  7 +-
 src/logic/EventuallyFormula.cpp               |  8 ++
 src/logic/EventuallyFormula.h                 |  4 +-
 src/logic/Formula.cpp                         | 34 +++-----
 src/logic/Formula.h                           | 12 +--
 src/logic/Formulas.h                          |  2 -
 src/logic/GloballyFormula.cpp                 |  6 +-
 src/logic/GloballyFormula.h                   |  3 +-
 src/logic/InstantaneousRewardFormula.cpp      |  4 +
 src/logic/InstantaneousRewardFormula.h        |  7 +-
 src/logic/LongRunAverageRewardFormula.cpp     |  4 +
 src/logic/LongRunAverageRewardFormula.h       | 10 +--
 src/logic/NextFormula.cpp                     |  4 +
 src/logic/NextFormula.h                       |  3 +-
 src/logic/ReachabilityRewardFormula.cpp       | 35 --------
 src/logic/ReachabilityRewardFormula.h         | 36 ---------
 src/logic/RewardOperatorFormula.cpp           |  3 +-
 src/logic/RewardPathFormula.cpp               |  9 ---
 src/logic/RewardPathFormula.h                 | 19 -----
 src/logic/UntilFormula.cpp                    |  4 +
 src/logic/UntilFormula.h                      |  3 +-
 src/modelchecker/AbstractModelChecker.cpp     | 80 ++++++++++---------
 src/modelchecker/AbstractModelChecker.h       |  4 +-
 src/modelchecker/CheckTask.h                  | 37 ++++++++-
 .../csl/HybridCtmcCslModelChecker.cpp         |  8 +-
 .../csl/HybridCtmcCslModelChecker.h           |  2 +-
 .../csl/SparseCtmcCslModelChecker.cpp         |  8 +-
 .../csl/SparseCtmcCslModelChecker.h           |  2 +-
 .../SparseMarkovAutomatonCslModelChecker.cpp  |  8 +-
 .../SparseMarkovAutomatonCslModelChecker.h    |  2 +-
 .../prctl/HybridDtmcPrctlModelChecker.cpp     |  8 +-
 .../prctl/HybridDtmcPrctlModelChecker.h       |  2 +-
 .../prctl/HybridMdpPrctlModelChecker.cpp      | 10 +--
 .../prctl/HybridMdpPrctlModelChecker.h        |  2 +-
 .../prctl/SparseDtmcPrctlModelChecker.cpp     | 10 +--
 .../prctl/SparseDtmcPrctlModelChecker.h       |  2 +-
 .../prctl/SparseMdpPrctlModelChecker.cpp      | 10 +--
 .../prctl/SparseMdpPrctlModelChecker.h        |  2 +-
 .../prctl/SymbolicDtmcPrctlModelChecker.cpp   | 10 +--
 .../prctl/SymbolicDtmcPrctlModelChecker.h     |  2 +-
 .../prctl/SymbolicMdpPrctlModelChecker.cpp    | 10 +--
 .../prctl/SymbolicMdpPrctlModelChecker.h      |  2 +-
 .../SparseDtmcEliminationModelChecker.cpp     | 15 ++--
 .../SparseDtmcEliminationModelChecker.h       |  2 +-
 src/parser/FormulaParser.cpp                  | 12 +--
 .../BisimulationDecomposition.cpp             |  5 --
 51 files changed, 212 insertions(+), 276 deletions(-)
 delete mode 100644 src/logic/ReachabilityRewardFormula.cpp
 delete mode 100644 src/logic/ReachabilityRewardFormula.h
 delete mode 100644 src/logic/RewardPathFormula.cpp
 delete mode 100644 src/logic/RewardPathFormula.h

diff --git a/src/logic/BoundedUntilFormula.cpp b/src/logic/BoundedUntilFormula.cpp
index 2c7ed2cde..7c29c579b 100644
--- a/src/logic/BoundedUntilFormula.cpp
+++ b/src/logic/BoundedUntilFormula.cpp
@@ -30,6 +30,10 @@ namespace storm {
             return bounds.which() == 0;
         }
         
+        bool BoundedUntilFormula::isValidProbabilityPathFormula() const {
+            return true;
+        }
+        
         bool BoundedUntilFormula::isPctlPathFormula() const {
             return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
         }
diff --git a/src/logic/BoundedUntilFormula.h b/src/logic/BoundedUntilFormula.h
index 4d72abdc1..7da7e70f6 100644
--- a/src/logic/BoundedUntilFormula.h
+++ b/src/logic/BoundedUntilFormula.h
@@ -22,6 +22,7 @@ namespace storm {
             std::pair<double, double> const& getIntervalBounds() const;
             uint_fast64_t getDiscreteTimeBound() const;
             
+            virtual bool isValidProbabilityPathFormula() const override;
             virtual bool isPctlPathFormula() const override;
             virtual bool isCslPathFormula() const override;
 
diff --git a/src/logic/ConditionalPathFormula.cpp b/src/logic/ConditionalPathFormula.cpp
index b5d8af81d..8ef461e35 100644
--- a/src/logic/ConditionalPathFormula.cpp
+++ b/src/logic/ConditionalPathFormula.cpp
@@ -10,6 +10,10 @@ namespace storm {
             return true;
         }
         
+        bool ConditionalPathFormula::isValidProbabilityPathFormula() const {
+            return true;
+        }
+        
         std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
         }
diff --git a/src/logic/ConditionalPathFormula.h b/src/logic/ConditionalPathFormula.h
index bd5f3852c..a3e12e20f 100644
--- a/src/logic/ConditionalPathFormula.h
+++ b/src/logic/ConditionalPathFormula.h
@@ -14,7 +14,8 @@ namespace storm {
             }
             
             virtual bool isConditionalPathFormula() const override;
-            
+            virtual bool isValidProbabilityPathFormula() const override;
+
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
diff --git a/src/logic/CumulativeRewardFormula.cpp b/src/logic/CumulativeRewardFormula.cpp
index ed4b18c85..3f53c2e9d 100644
--- a/src/logic/CumulativeRewardFormula.cpp
+++ b/src/logic/CumulativeRewardFormula.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return true;
         }
         
+        bool CumulativeRewardFormula::isValidRewardPathFormula() const {
+            return true;
+        }
+        
         bool CumulativeRewardFormula::hasDiscreteTimeBound() const {
             return timeBound.which() == 0;
         }
diff --git a/src/logic/CumulativeRewardFormula.h b/src/logic/CumulativeRewardFormula.h
index 8b8692743..4ebf08cd4 100644
--- a/src/logic/CumulativeRewardFormula.h
+++ b/src/logic/CumulativeRewardFormula.h
@@ -3,11 +3,11 @@
 
 #include <boost/variant.hpp>
 
-#include "src/logic/RewardPathFormula.h"
+#include "src/logic/PathFormula.h"
 
 namespace storm {
     namespace logic {
-        class CumulativeRewardFormula : public RewardPathFormula {
+        class CumulativeRewardFormula : public PathFormula {
         public:
             CumulativeRewardFormula(uint_fast64_t timeBound);
             
@@ -18,7 +18,8 @@ namespace storm {
             }
             
             virtual bool isCumulativeRewardFormula() const override;
-            
+            virtual bool isValidRewardPathFormula() const override;
+
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             bool hasDiscreteTimeBound() const;
diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp
index b8ea1aa35..a25d12b33 100644
--- a/src/logic/EventuallyFormula.cpp
+++ b/src/logic/EventuallyFormula.cpp
@@ -10,6 +10,14 @@ namespace storm {
             return true;
         }
         
+        bool EventuallyFormula::isValidProbabilityPathFormula() const {
+            return true;
+        }
+        
+        bool EventuallyFormula::isValidRewardPathFormula() const {
+            return true;
+        }
+        
         std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution));
         }
diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h
index 816f93c82..a488eb443 100644
--- a/src/logic/EventuallyFormula.h
+++ b/src/logic/EventuallyFormula.h
@@ -14,7 +14,9 @@ namespace storm {
             }
             
             virtual bool isEventuallyFormula() const override;
-            
+            virtual bool isValidProbabilityPathFormula() const override;
+            virtual bool isValidRewardPathFormula() const override;
+
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp
index 5ba068af9..e3fa84c74 100644
--- a/src/logic/Formula.cpp
+++ b/src/logic/Formula.cpp
@@ -87,10 +87,6 @@ namespace storm {
             return false;
         }
         
-        bool Formula::isRewardPathFormula() const {
-            return false;
-        }
-        
         bool Formula::isCumulativeRewardFormula() const {
             return false;
         }
@@ -99,10 +95,6 @@ namespace storm {
             return false;
         }
         
-        bool Formula::isReachabilityRewardFormula() const {
-            return false;
-        }
-        
         bool Formula::isLongRunAverageRewardFormula() const {
             return false;
         }
@@ -147,6 +139,14 @@ namespace storm {
             return false;
         }
         
+        bool Formula::isValidProbabilityPathFormula() const {
+            return false;
+        }
+        
+        bool Formula::isValidRewardPathFormula() const {
+            return false;
+        }
+        
         bool Formula::containsBoundedUntilFormula() const {
             return false;
         }
@@ -327,14 +327,6 @@ namespace storm {
             return dynamic_cast<ExpectedTimeOperatorFormula const&>(*this);
         }
         
-        RewardPathFormula& Formula::asRewardPathFormula() {
-            return dynamic_cast<RewardPathFormula&>(*this);
-        }
-        
-        RewardPathFormula const& Formula::asRewardPathFormula() const {
-            return dynamic_cast<RewardPathFormula const&>(*this);
-        }
-        
         CumulativeRewardFormula& Formula::asCumulativeRewardFormula() {
             return dynamic_cast<CumulativeRewardFormula&>(*this);
         }
@@ -350,15 +342,7 @@ namespace storm {
         InstantaneousRewardFormula const& Formula::asInstantaneousRewardFormula() const {
             return dynamic_cast<InstantaneousRewardFormula const&>(*this);
         }
-        
-        ReachabilityRewardFormula& Formula::asReachabilityRewardFormula() {
-            return dynamic_cast<ReachabilityRewardFormula&>(*this);
-        }
-        
-        ReachabilityRewardFormula const& Formula::asReachabilityRewardFormula() const {
-            return dynamic_cast<ReachabilityRewardFormula const&>(*this);
-        }
-        
+                
         LongRunAverageRewardFormula& Formula::asLongRunAverageRewardFormula() {
             return dynamic_cast<LongRunAverageRewardFormula&>(*this);
         }
diff --git a/src/logic/Formula.h b/src/logic/Formula.h
index 31ee7744a..2ea234449 100644
--- a/src/logic/Formula.h
+++ b/src/logic/Formula.h
@@ -31,10 +31,8 @@ namespace storm {
         class NextFormula;
         class LongRunAverageOperatorFormula;
         class ExpectedTimeOperatorFormula;
-        class RewardPathFormula;
         class CumulativeRewardFormula;
         class InstantaneousRewardFormula;
-        class ReachabilityRewardFormula;
         class LongRunAverageRewardFormula;
         class ProbabilityOperatorFormula;
         class RewardOperatorFormula;
@@ -74,10 +72,8 @@ namespace storm {
             virtual bool isNextFormula() const;
             virtual bool isLongRunAverageOperatorFormula() const;
             virtual bool isExpectedTimeOperatorFormula() const;
-            virtual bool isRewardPathFormula() const;
             virtual bool isCumulativeRewardFormula() const;
             virtual bool isInstantaneousRewardFormula() const;
-            virtual bool isReachabilityRewardFormula() const;
             virtual bool isLongRunAverageRewardFormula() const;
             virtual bool isProbabilityOperatorFormula() const;
             virtual bool isRewardOperatorFormula() const;
@@ -90,6 +86,8 @@ namespace storm {
             virtual bool isPltlFormula() const;
             virtual bool isLtlFormula() const;
             virtual bool isPropositionalFormula() const;
+            virtual bool isValidProbabilityPathFormula() const;
+            virtual bool isValidRewardPathFormula() const;
             virtual bool containsBoundedUntilFormula() const;
             virtual bool containsNextFormula() const;
             virtual bool containsProbabilityOperator() const;
@@ -156,18 +154,12 @@ namespace storm {
             ExpectedTimeOperatorFormula& asExpectedTimeOperatorFormula();
             ExpectedTimeOperatorFormula const& asExpectedTimeOperatorFormula() const;
             
-            RewardPathFormula& asRewardPathFormula();
-            RewardPathFormula const& asRewardPathFormula() const;
-            
             CumulativeRewardFormula& asCumulativeRewardFormula();
             CumulativeRewardFormula const& asCumulativeRewardFormula() const;
             
             InstantaneousRewardFormula& asInstantaneousRewardFormula();
             InstantaneousRewardFormula const& asInstantaneousRewardFormula() const;
             
-            ReachabilityRewardFormula& asReachabilityRewardFormula();
-            ReachabilityRewardFormula const& asReachabilityRewardFormula() const;
-
             LongRunAverageRewardFormula& asLongRunAverageRewardFormula();
             LongRunAverageRewardFormula const& asLongRunAverageRewardFormula() const;
             
diff --git a/src/logic/Formulas.h b/src/logic/Formulas.h
index 3671b2859..7da9321c6 100644
--- a/src/logic/Formulas.h
+++ b/src/logic/Formulas.h
@@ -12,10 +12,8 @@
 #include "src/logic/InstantaneousRewardFormula.h"
 #include "src/logic/NextFormula.h"
 #include "src/logic/PathFormula.h"
-#include "src/logic/RewardPathFormula.h"
 #include "src/logic/OperatorFormula.h"
 #include "src/logic/ProbabilityOperatorFormula.h"
-#include "src/logic/ReachabilityRewardFormula.h"
 #include "src/logic/LongRunAverageRewardFormula.h"
 #include "src/logic/RewardOperatorFormula.h"
 #include "src/logic/StateFormula.h"
diff --git a/src/logic/GloballyFormula.cpp b/src/logic/GloballyFormula.cpp
index 8d2d1c92a..5ddfd8feb 100644
--- a/src/logic/GloballyFormula.cpp
+++ b/src/logic/GloballyFormula.cpp
@@ -9,7 +9,11 @@ namespace storm {
         bool GloballyFormula::isGloballyFormula() const {
             return true;
         }
-        
+
+        bool GloballyFormula::isValidProbabilityPathFormula() const {
+            return true;
+        }
+
         std::shared_ptr<Formula> GloballyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<GloballyFormula>(this->getSubformula().substitute(substitution));
         }
diff --git a/src/logic/GloballyFormula.h b/src/logic/GloballyFormula.h
index 6346200c8..e3fc82f2d 100644
--- a/src/logic/GloballyFormula.h
+++ b/src/logic/GloballyFormula.h
@@ -14,7 +14,8 @@ namespace storm {
             }
             
             virtual bool isGloballyFormula() const override;
-            
+            virtual bool isValidProbabilityPathFormula() const override;
+
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
             virtual std::ostream& writeToStream(std::ostream& out) const override;
diff --git a/src/logic/InstantaneousRewardFormula.cpp b/src/logic/InstantaneousRewardFormula.cpp
index 7d81f1234..77efb5705 100644
--- a/src/logic/InstantaneousRewardFormula.cpp
+++ b/src/logic/InstantaneousRewardFormula.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return true;
         }
         
+        bool InstantaneousRewardFormula::isValidRewardPathFormula() const {
+            return true;
+        }
+        
         bool InstantaneousRewardFormula::hasDiscreteTimeBound() const {
             return timeBound.which() == 0;
         }
diff --git a/src/logic/InstantaneousRewardFormula.h b/src/logic/InstantaneousRewardFormula.h
index 8b29fa740..c895c5b39 100644
--- a/src/logic/InstantaneousRewardFormula.h
+++ b/src/logic/InstantaneousRewardFormula.h
@@ -3,11 +3,11 @@
 
 #include <boost/variant.hpp>
 
-#include "src/logic/RewardPathFormula.h"
+#include "src/logic/PathFormula.h"
 
 namespace storm {
     namespace logic {
-        class InstantaneousRewardFormula : public RewardPathFormula {
+        class InstantaneousRewardFormula : public PathFormula {
         public:
             InstantaneousRewardFormula(uint_fast64_t timeBound);
             
@@ -18,7 +18,8 @@ namespace storm {
             }
             
             virtual bool isInstantaneousRewardFormula() const override;
-            
+            virtual bool isValidRewardPathFormula() const override;
+
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             bool hasDiscreteTimeBound() const;
diff --git a/src/logic/LongRunAverageRewardFormula.cpp b/src/logic/LongRunAverageRewardFormula.cpp
index 896e94a31..7bc064c1e 100644
--- a/src/logic/LongRunAverageRewardFormula.cpp
+++ b/src/logic/LongRunAverageRewardFormula.cpp
@@ -10,6 +10,10 @@ namespace storm {
             return true;
         }
         
+        bool LongRunAverageRewardFormula::isValidRewardPathFormula() const {
+            return true;
+        }
+        
         std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::shared_ptr<Formula>(new LongRunAverageRewardFormula());
         }
diff --git a/src/logic/LongRunAverageRewardFormula.h b/src/logic/LongRunAverageRewardFormula.h
index 449d5fd0e..aa4d3f424 100644
--- a/src/logic/LongRunAverageRewardFormula.h
+++ b/src/logic/LongRunAverageRewardFormula.h
@@ -1,14 +1,11 @@
 #ifndef STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_
 #define STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_
 
-#include <memory>
-
-#include "src/logic/RewardPathFormula.h"
-
+#include "src/logic/PathFormula.h"
 
 namespace storm {
     namespace logic {
-        class LongRunAverageRewardFormula : public RewardPathFormula {
+        class LongRunAverageRewardFormula : public PathFormula {
         public:
             LongRunAverageRewardFormula();
             
@@ -17,7 +14,8 @@ namespace storm {
             }
             
             virtual bool isLongRunAverageRewardFormula() const override;
-            
+            virtual bool isValidRewardPathFormula() const override;
+
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
             virtual std::ostream& writeToStream(std::ostream& out) const override;
diff --git a/src/logic/NextFormula.cpp b/src/logic/NextFormula.cpp
index b5064253f..b7400eb7d 100644
--- a/src/logic/NextFormula.cpp
+++ b/src/logic/NextFormula.cpp
@@ -10,6 +10,10 @@ namespace storm {
             return true;
         }
         
+        bool NextFormula::isValidProbabilityPathFormula() const {
+            return true;
+        }
+        
         bool NextFormula::containsNextFormula() const {
             return true;
         }
diff --git a/src/logic/NextFormula.h b/src/logic/NextFormula.h
index 2466d0b3d..f0de43cc6 100644
--- a/src/logic/NextFormula.h
+++ b/src/logic/NextFormula.h
@@ -14,7 +14,8 @@ namespace storm {
             }
             
             virtual bool isNextFormula() const override;
-            
+            virtual bool isValidProbabilityPathFormula() const override;
+
             virtual bool containsNextFormula() const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
diff --git a/src/logic/ReachabilityRewardFormula.cpp b/src/logic/ReachabilityRewardFormula.cpp
deleted file mode 100644
index 83ba52f91..000000000
--- a/src/logic/ReachabilityRewardFormula.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "src/logic/ReachabilityRewardFormula.h"
-
-namespace storm {
-    namespace logic {
-        ReachabilityRewardFormula::ReachabilityRewardFormula(std::shared_ptr<Formula const> const& subformula) : subformula(subformula) {
-            // Intentionally left empty.
-        }
-        
-        bool ReachabilityRewardFormula::isReachabilityRewardFormula() const {
-            return true;
-        }
-        
-        Formula const& ReachabilityRewardFormula::getSubformula() const {
-            return *subformula;
-        }
-        
-        void ReachabilityRewardFormula::gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const {
-            this->getSubformula().gatherAtomicExpressionFormulas(atomicExpressionFormulas);
-        }
-        
-        void ReachabilityRewardFormula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const {
-            this->getSubformula().gatherAtomicLabelFormulas(atomicLabelFormulas);
-        }
-        
-        std::shared_ptr<Formula> ReachabilityRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
-            return std::make_shared<ReachabilityRewardFormula>(this->getSubformula().substitute(substitution));
-        }
-        
-        std::ostream& ReachabilityRewardFormula::writeToStream(std::ostream& out) const {
-            out << "F ";
-            this->getSubformula().writeToStream(out);
-            return out;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/logic/ReachabilityRewardFormula.h b/src/logic/ReachabilityRewardFormula.h
deleted file mode 100644
index bfef88188..000000000
--- a/src/logic/ReachabilityRewardFormula.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef STORM_LOGIC_REACHABILITYREWARDFORMULA_H_
-#define STORM_LOGIC_REACHABILITYREWARDFORMULA_H_
-
-#include <memory>
-
-#include "src/logic/RewardPathFormula.h"
-
-
-namespace storm {
-    namespace logic {
-        class ReachabilityRewardFormula : public RewardPathFormula {
-        public:
-            ReachabilityRewardFormula(std::shared_ptr<Formula const> const& subformula);
-            
-            virtual ~ReachabilityRewardFormula() {
-                // Intentionally left empty.
-            }
-            
-            virtual bool isReachabilityRewardFormula() const override;
-            
-            Formula const& getSubformula() const;
-            
-            virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override;
-            virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const override;
-            
-            virtual std::ostream& writeToStream(std::ostream& out) const override;
-            
-            virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
-            
-        private:
-            std::shared_ptr<Formula const> subformula;
-        };
-    }
-}
-
-#endif /* STORM_LOGIC_REACHABILITYREWARDFORMULA_H_ */
\ No newline at end of file
diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp
index 791d1f5cc..1e5390830 100644
--- a/src/logic/RewardOperatorFormula.cpp
+++ b/src/logic/RewardOperatorFormula.cpp
@@ -23,7 +23,8 @@ namespace storm {
         }
         
         bool RewardOperatorFormula::isPctlStateFormula() const {
-            return this->getSubformula().isRewardPathFormula();
+            Formula const& subformula = this->getSubformula();
+            return subformula.isEventuallyFormula() || subformula.isCumulativeRewardFormula() || subformula.isInstantaneousRewardFormula();
         }
         
         bool RewardOperatorFormula::containsRewardOperator() const {
diff --git a/src/logic/RewardPathFormula.cpp b/src/logic/RewardPathFormula.cpp
deleted file mode 100644
index 3c97acf74..000000000
--- a/src/logic/RewardPathFormula.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "src/logic/RewardPathFormula.h"
-
-namespace storm {
-    namespace logic {
-        bool RewardPathFormula::isRewardPathFormula() const {
-            return true;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/logic/RewardPathFormula.h b/src/logic/RewardPathFormula.h
deleted file mode 100644
index 023e76e2d..000000000
--- a/src/logic/RewardPathFormula.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef STORM_LOGIC_PATHREWARDFORMULA_H_
-#define STORM_LOGIC_PATHREWARDFORMULA_H_
-
-#include "src/logic/PathFormula.h"
-
-namespace storm {
-    namespace logic {
-        class RewardPathFormula : public Formula {
-        public:
-            virtual ~RewardPathFormula() {
-                // Intentionally left empty.
-            }
-            
-            virtual bool isRewardPathFormula() const override;
-        };
-    }
-}
-
-#endif /* STORM_LOGIC_PATHREWARDFORMULA_H_ */
\ No newline at end of file
diff --git a/src/logic/UntilFormula.cpp b/src/logic/UntilFormula.cpp
index 94d7c62a8..b15f3743f 100644
--- a/src/logic/UntilFormula.cpp
+++ b/src/logic/UntilFormula.cpp
@@ -10,6 +10,10 @@ namespace storm {
             return true;
         }
         
+        bool UntilFormula::isValidProbabilityPathFormula() const {
+            return true;
+        }
+        
         std::shared_ptr<Formula> UntilFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<UntilFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
         }
diff --git a/src/logic/UntilFormula.h b/src/logic/UntilFormula.h
index 45a721252..87ceef806 100644
--- a/src/logic/UntilFormula.h
+++ b/src/logic/UntilFormula.h
@@ -14,7 +14,8 @@ namespace storm {
             }
             
             virtual bool isUntilFormula() const override;
-            
+            virtual bool isValidProbabilityPathFormula() const override;
+
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
             virtual std::ostream& writeToStream(std::ostream& out) const override;
diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index 3b0d55ebf..56a65b39e 100644
--- a/src/modelchecker/AbstractModelChecker.cpp
+++ b/src/modelchecker/AbstractModelChecker.cpp
@@ -15,11 +15,13 @@ namespace storm {
             storm::logic::Formula const& formula = checkTask.getFormula();
             STORM_LOG_THROW(this->canHandle(formula), storm::exceptions::InvalidArgumentException, "The model checker is not able to check the formula '" << formula << "'.");
             if (formula.isStateFormula()) {
-                return this->checkStateFormula(checkTask.replaceFormula(formula.asStateFormula()));
+                return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula()));
             } else if (formula.isPathFormula()) {
-                return this->computeProbabilities(checkTask.replaceFormula(formula.asPathFormula()));
-            } else if (formula.isRewardPathFormula()) {
-                return this->computeRewards(checkTask.replaceFormula(formula.asRewardPathFormula()));
+                if (checkTask.computeProbabilities()) {
+                    return this->computeProbabilities(checkTask.substituteFormula(formula.asPathFormula()));
+                } else if (checkTask.computeRewards()) {
+                    return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula()));
+                }
             }
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid.");
         }
@@ -27,17 +29,17 @@ namespace storm {
         std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask) {
             storm::logic::PathFormula const& pathFormula = checkTask.getFormula();
             if (pathFormula.isBoundedUntilFormula()) {
-                return this->computeBoundedUntilProbabilities(checkTask.replaceFormula(pathFormula.asBoundedUntilFormula()));
+                return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(pathFormula.asBoundedUntilFormula()));
             } else if (pathFormula.isConditionalPathFormula()) {
-                return this->computeConditionalProbabilities(checkTask.replaceFormula(pathFormula.asConditionalPathFormula()));
+                return this->computeConditionalProbabilities(checkTask.substituteFormula(pathFormula.asConditionalPathFormula()));
             } else if (pathFormula.isEventuallyFormula()) {
-                return this->computeEventuallyProbabilities(checkTask.replaceFormula(pathFormula.asEventuallyFormula()));
+                return this->computeEventuallyProbabilities(checkTask.substituteFormula(pathFormula.asEventuallyFormula()));
             } else if (pathFormula.isGloballyFormula()) {
-                return this->computeGloballyProbabilities(checkTask.replaceFormula(pathFormula.asGloballyFormula()));
+                return this->computeGloballyProbabilities(checkTask.substituteFormula(pathFormula.asGloballyFormula()));
             } else if (pathFormula.isUntilFormula()) {
-                return this->computeUntilProbabilities(checkTask.replaceFormula(pathFormula.asUntilFormula()));
+                return this->computeUntilProbabilities(checkTask.substituteFormula(pathFormula.asUntilFormula()));
             } else if (pathFormula.isNextFormula()) {
-                return this->computeNextProbabilities(checkTask.replaceFormula(pathFormula.asNextFormula()));
+                return this->computeNextProbabilities(checkTask.substituteFormula(pathFormula.asNextFormula()));
             }
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << pathFormula << "' is invalid.");
         }
@@ -53,7 +55,7 @@ namespace storm {
         std::unique_ptr<CheckResult> AbstractModelChecker::computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
             storm::logic::EventuallyFormula const& pathFormula = checkTask.getFormula();
             storm::logic::UntilFormula newFormula(storm::logic::Formula::getTrueFormula(), pathFormula.getSubformula().asSharedPointer());
-            return this->computeUntilProbabilities(checkTask.replaceFormula(newFormula));
+            return this->computeUntilProbabilities(checkTask.substituteFormula(newFormula));
         }
         
         std::unique_ptr<CheckResult> AbstractModelChecker::computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) {
@@ -68,16 +70,16 @@ namespace storm {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
         
-        std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::RewardPathFormula> const& checkTask) {
-            storm::logic::RewardPathFormula const& rewardPathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask) {
+            storm::logic::PathFormula const& rewardPathFormula = checkTask.getFormula();
             if (rewardPathFormula.isCumulativeRewardFormula()) {
-                return this->computeCumulativeRewards(checkTask.replaceFormula(rewardPathFormula.asCumulativeRewardFormula()));
+                return this->computeCumulativeRewards(checkTask.substituteFormula(rewardPathFormula.asCumulativeRewardFormula()));
             } else if (rewardPathFormula.isInstantaneousRewardFormula()) {
-                return this->computeInstantaneousRewards(checkTask.replaceFormula(rewardPathFormula.asInstantaneousRewardFormula()));
-            } else if (rewardPathFormula.isReachabilityRewardFormula()) {
-                return this->computeReachabilityRewards(checkTask.replaceFormula(rewardPathFormula.asReachabilityRewardFormula()));
+                return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardPathFormula.asInstantaneousRewardFormula()));
+            } else if (rewardPathFormula.isEventuallyFormula()) {
+                return this->computeReachabilityRewards(checkTask.substituteFormula(rewardPathFormula.asEventuallyFormula()));
             } else if (rewardPathFormula.isLongRunAverageRewardFormula()) {
-                return this->computeLongRunAverageRewards(checkTask.replaceFormula(rewardPathFormula.asLongRunAverageRewardFormula()));
+                return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardPathFormula.asLongRunAverageRewardFormula()));
             }
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid.");
         }
@@ -90,7 +92,7 @@ namespace storm {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
         
-        std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
+        std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
         
@@ -109,25 +111,25 @@ namespace storm {
         std::unique_ptr<CheckResult> AbstractModelChecker::checkStateFormula(CheckTask<storm::logic::StateFormula> const& checkTask) {
             storm::logic::StateFormula const& stateFormula = checkTask.getFormula();
             if (stateFormula.isBinaryBooleanStateFormula()) {
-                return this->checkBinaryBooleanStateFormula(checkTask.replaceFormula(stateFormula.asBinaryBooleanStateFormula()));
+                return this->checkBinaryBooleanStateFormula(checkTask.substituteFormula(stateFormula.asBinaryBooleanStateFormula()));
             } else if (stateFormula.isUnaryBooleanStateFormula()) {
-                return this->checkUnaryBooleanStateFormula(checkTask.replaceFormula(stateFormula.asUnaryBooleanStateFormula()));
+                return this->checkUnaryBooleanStateFormula(checkTask.substituteFormula(stateFormula.asUnaryBooleanStateFormula()));
             } else if (stateFormula.isBooleanLiteralFormula()) {
-                return this->checkBooleanLiteralFormula(checkTask.replaceFormula(stateFormula.asBooleanLiteralFormula()));
+                return this->checkBooleanLiteralFormula(checkTask.substituteFormula(stateFormula.asBooleanLiteralFormula()));
             } else if (stateFormula.isProbabilityOperatorFormula()) {
-                return this->checkProbabilityOperatorFormula(checkTask.replaceFormula(stateFormula.asProbabilityOperatorFormula()));
+                return this->checkProbabilityOperatorFormula(checkTask.substituteFormula(stateFormula.asProbabilityOperatorFormula()));
             } else if (stateFormula.isRewardOperatorFormula()) {
-                return this->checkRewardOperatorFormula(checkTask.replaceFormula(stateFormula.asRewardOperatorFormula()));
+                return this->checkRewardOperatorFormula(checkTask.substituteFormula(stateFormula.asRewardOperatorFormula()));
             } else if (stateFormula.isExpectedTimeOperatorFormula()) {
-                return this->checkExpectedTimeOperatorFormula(checkTask.replaceFormula(stateFormula.asExpectedTimeOperatorFormula()));
+                return this->checkExpectedTimeOperatorFormula(checkTask.substituteFormula(stateFormula.asExpectedTimeOperatorFormula()));
             } else if (stateFormula.isLongRunAverageOperatorFormula()) {
-                return this->checkLongRunAverageOperatorFormula(checkTask.replaceFormula(stateFormula.asLongRunAverageOperatorFormula()));
+                return this->checkLongRunAverageOperatorFormula(checkTask.substituteFormula(stateFormula.asLongRunAverageOperatorFormula()));
             } else if (stateFormula.isAtomicExpressionFormula()) {
-                return this->checkAtomicExpressionFormula(checkTask.replaceFormula(stateFormula.asAtomicExpressionFormula()));
+                return this->checkAtomicExpressionFormula(checkTask.substituteFormula(stateFormula.asAtomicExpressionFormula()));
             } else if (stateFormula.isAtomicLabelFormula()) {
-                return this->checkAtomicLabelFormula(checkTask.replaceFormula(stateFormula.asAtomicLabelFormula()));
+                return this->checkAtomicLabelFormula(checkTask.substituteFormula(stateFormula.asAtomicLabelFormula()));
             } else if (stateFormula.isBooleanLiteralFormula()) {
-                return this->checkBooleanLiteralFormula(checkTask.replaceFormula(stateFormula.asBooleanLiteralFormula()));
+                return this->checkBooleanLiteralFormula(checkTask.substituteFormula(stateFormula.asBooleanLiteralFormula()));
             }
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << stateFormula << "' is invalid.");
         }
@@ -136,7 +138,7 @@ namespace storm {
             storm::logic::AtomicExpressionFormula const& stateFormula = checkTask.getFormula();
             std::stringstream stream;
             stream << stateFormula.getExpression();
-            return this->checkAtomicLabelFormula(checkTask.replaceFormula(storm::logic::AtomicLabelFormula(stream.str())));
+            return this->checkAtomicLabelFormula(checkTask.substituteFormula(storm::logic::AtomicLabelFormula(stream.str())));
         }
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkAtomicLabelFormula(CheckTask<storm::logic::AtomicLabelFormula> const& checkTask) {
@@ -147,8 +149,8 @@ namespace storm {
             storm::logic::BinaryBooleanStateFormula const& stateFormula = checkTask.getFormula();
             STORM_LOG_THROW(stateFormula.getLeftSubformula().isStateFormula() && stateFormula.getRightSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
             
-            std::unique_ptr<CheckResult> leftResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getLeftSubformula().asStateFormula()));
-            std::unique_ptr<CheckResult> rightResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getRightSubformula().asStateFormula()));
+            std::unique_ptr<CheckResult> leftResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getLeftSubformula().asStateFormula()));
+            std::unique_ptr<CheckResult> rightResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getRightSubformula().asStateFormula()));
             
             STORM_LOG_THROW(leftResult->isQualitative() && rightResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative results.");
             
@@ -169,9 +171,9 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) {
             storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula();
-            STORM_LOG_THROW(stateFormula.getSubformula().isPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
+            STORM_LOG_THROW(stateFormula.getSubformula().isValidProbabilityPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
             
-            std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.replaceFormula(stateFormula.getSubformula().asPathFormula()));
+            std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula()));
             
             if (stateFormula.hasBound()) {
                 STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@@ -183,9 +185,9 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) {
             storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula();
-            STORM_LOG_THROW(stateFormula.getSubformula().isRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
+            STORM_LOG_THROW(stateFormula.getSubformula().isValidRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
             
-            std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.replaceFormula(stateFormula.getSubformula().asRewardPathFormula()));
+            std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula()));
             
             if (checkTask.isBoundSet()) {
                 STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@@ -199,7 +201,7 @@ namespace storm {
             storm::logic::ExpectedTimeOperatorFormula const& stateFormula = checkTask.getFormula();
 			STORM_LOG_THROW(stateFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
             
-            std::unique_ptr<CheckResult> result = this->computeExpectedTimes(checkTask.replaceFormula(stateFormula.getSubformula().asEventuallyFormula()));
+            std::unique_ptr<CheckResult> result = this->computeExpectedTimes(checkTask.substituteFormula(stateFormula.getSubformula().asEventuallyFormula()));
             
             if (checkTask.isBoundSet()) {
                 STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@@ -213,7 +215,7 @@ namespace storm {
             storm::logic::LongRunAverageOperatorFormula const& stateFormula = checkTask.getFormula();
 			STORM_LOG_THROW(stateFormula.getSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
             
-            std::unique_ptr<CheckResult> result = this->computeLongRunAverageProbabilities(checkTask.replaceFormula(stateFormula.getSubformula().asStateFormula()));
+            std::unique_ptr<CheckResult> result = this->computeLongRunAverageProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asStateFormula()));
             
             if (checkTask.isBoundSet()) {
                 STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@@ -225,7 +227,7 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkUnaryBooleanStateFormula(CheckTask<storm::logic::UnaryBooleanStateFormula> const& checkTask) {
             storm::logic::UnaryBooleanStateFormula const& stateFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> subResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getSubformula()));
+            std::unique_ptr<CheckResult> subResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getSubformula()));
             STORM_LOG_THROW(subResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative result.");
             if (stateFormula.isNot()) {
                 subResult->asQualitativeCheckResult().complement();
diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h
index a4ad1b6ac..f827c99ff 100644
--- a/src/modelchecker/AbstractModelChecker.h
+++ b/src/modelchecker/AbstractModelChecker.h
@@ -44,10 +44,10 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask);
             
             // The methods to compute the rewards for path formulas.
-            virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::RewardPathFormula> const& checkTask);
+            virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask);
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask);
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask);
             
             // The methods to compute the long-run average and expected time.
diff --git a/src/modelchecker/CheckTask.h b/src/modelchecker/CheckTask.h
index be56e29e1..a780ef168 100644
--- a/src/modelchecker/CheckTask.h
+++ b/src/modelchecker/CheckTask.h
@@ -16,6 +16,10 @@ namespace storm {
     
     namespace modelchecker {
         
+        enum class CheckType {
+            Probabilities, Rewards
+        };
+        
         /*
          * This class is used to customize the checking process of a formula.
          */
@@ -59,6 +63,8 @@ namespace storm {
                         }
                     }
                 } else if (formula.isRewardOperatorFormula()) {
+                    this->checkType = CheckType::Rewards;
+                    
                     storm::logic::RewardOperatorFormula const& rewardOperatorFormula = formula.asRewardOperatorFormula();
                     this->rewardModel = rewardOperatorFormula.getOptionalRewardModelName();
                     
@@ -75,8 +81,8 @@ namespace storm {
              * changes the formula type of the check task object.
              */
             template<typename NewFormulaType>
-            CheckTask<NewFormulaType, ValueType> replaceFormula(NewFormulaType const& newFormula) const {
-                return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers);
+            CheckTask<NewFormulaType, ValueType> substituteFormula(NewFormulaType const& newFormula) const {
+                return CheckTask<NewFormulaType, ValueType>(newFormula, this->checkType, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers);
             }
             
             /*!
@@ -85,6 +91,27 @@ namespace storm {
             FormulaType const& getFormula() const {
                 return formula.get();
             }
+
+            /*!
+             * Retrieves whether probabilities are to be computed.
+             */
+            bool computeProbabilities() const {
+                return checkType == CheckType::Probabilities;
+            }
+            
+            /*!
+             * Retrieves whether rewards are to be computed.
+             */
+            bool computeRewards() const {
+                return checkType == CheckType::Rewards;
+            }
+            
+            /*!
+             * Retrieves the type of this task.
+             */
+            CheckType getCheckType() const {
+                return checkType;
+            }
             
             /*!
              * Retrieves whether an optimization direction was set.
@@ -184,6 +211,7 @@ namespace storm {
              * Creates a task object with the given options.
              *
              * @param formula The formula to attach to the task.
+             * @param checkType The type of task: whether to compute probabilities or rewards.
              * @param optimizationDirection If set, the probabilities will be minimized/maximized.
              * @param rewardModelName If given, the checking has to be done wrt. to this reward model.
              * @param onlyInitialStatesRelevant If set to true, the model checker may decide to only compute the values
@@ -194,13 +222,16 @@ namespace storm {
              * @param produceSchedulers If supported by the model checker and the model formalism, schedulers to achieve
              * a value will be produced if this flag is set.
              */
-            CheckTask(std::reference_wrapper<FormulaType const> const& formula, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) {
+            CheckTask(std::reference_wrapper<FormulaType const> const& formula, CheckType checkType, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), checkType(checkType), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) {
                 // Intentionally left empty.
             }
             
             // The formula that is to be checked.
             std::reference_wrapper<FormulaType const> formula;
             
+            // A type indicating whether probabilities or rewards are to be computed.
+            CheckType checkType;
+            
             // If set, the probabilities will be minimized/maximized.
             boost::optional<storm::OptimizationDirection> optimizationDirection;
 
diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
index a5eb27b27..412ab836c 100644
--- a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
+++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
@@ -25,7 +25,7 @@ namespace storm {
         template<storm::dd::DdType DdType, class ValueType>
         bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslStateFormula() || formula.isCslPathFormula() || formula.isRewardPathFormula();
+            return formula.isCslStateFormula() || formula.isCslPathFormula();
         }
                 
         template<storm::dd::DdType DdType, class ValueType>
@@ -54,9 +54,9 @@ namespace storm {
         }
         
         template<storm::dd::DdType DdType, class ValueType>
-        std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+        std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
 
             return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);
diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.h b/src/modelchecker/csl/HybridCtmcCslModelChecker.h
index ace5b420b..d1e26bcb2 100644
--- a/src/modelchecker/csl/HybridCtmcCslModelChecker.h
+++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.h
@@ -23,7 +23,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
 
         protected:
diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
index b06cc2a54..e91547e81 100644
--- a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
+++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
@@ -32,7 +32,7 @@ namespace storm {
         template <typename SparseCtmcModelType>
         bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslStateFormula() || formula.isCslPathFormula() || formula.isRewardPathFormula();
+            return formula.isCslStateFormula() || formula.isCslPathFormula();
         }
         
         template <typename SparseCtmcModelType>
@@ -91,9 +91,9 @@ namespace storm {
         }
                 
         template <typename SparseCtmcModelType>
-        std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+        std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
             
             std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);
diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.h b/src/modelchecker/csl/SparseCtmcCslModelChecker.h
index d4e36071a..8def83dc7 100644
--- a/src/modelchecker/csl/SparseCtmcCslModelChecker.h
+++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.h
@@ -26,7 +26,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
 
         private:
diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
index b33b01436..b5966bf4c 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
@@ -30,7 +30,7 @@ namespace storm {
         template<typename SparseMarkovAutomatonModelType>
         bool SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslStateFormula() || formula.isCslPathFormula() || (formula.isRewardPathFormula() && formula.isReachabilityRewardFormula());
+            return formula.isCslStateFormula() || formula.isCslPathFormula();
         }
         
         template<typename SparseMarkovAutomatonModelType>
@@ -59,11 +59,11 @@ namespace storm {
         }
                 
         template<typename SparseMarkovAutomatonModelType>
-        std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
             STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
             STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute reachability rewards in non-closed Markov automaton.");
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
 
             std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory);
diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
index e57f9d3e5..4e4f60850 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
@@ -23,7 +23,7 @@ namespace storm {
             virtual bool canHandle(CheckTask<storm::logic::Formula> const& checkTask) const override;
             virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeExpectedTimes(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             
diff --git a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
index c5e2225aa..b9b0bec0a 100644
--- a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
@@ -36,7 +36,7 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool HybridDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula();
+            return formula.isPctlStateFormula() || formula.isPctlPathFormula();
         }
                 
         template<storm::dd::DdType DdType, typename ValueType>
@@ -91,9 +91,9 @@ namespace storm {
         }
         
         template<storm::dd::DdType DdType, typename ValueType>
-        std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+        std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
             return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
         }
diff --git a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h
index 4d64f6f17..b723ea699 100644
--- a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h
+++ b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h
@@ -24,7 +24,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
 
         protected:
diff --git a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
index 6dfd0d83b..cd39e8c62 100644
--- a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
@@ -30,11 +30,11 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool HybridMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) {
+            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
                 return true;
             }
             if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
             }
             if (formula.isGloballyFormula()) {
                 return true;
@@ -100,10 +100,10 @@ namespace storm {
         }
                 
         template<storm::dd::DdType DdType, typename ValueType>
-        std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
             STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
             return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
         }
diff --git a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h
index 78612a378..ec3ef2955 100644
--- a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h
+++ b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h
@@ -31,7 +31,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             
         protected:
             storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override;
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
index d4bb73950..dce8a8138 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
@@ -34,14 +34,14 @@ namespace storm {
         template<typename SparseDtmcModelType>
         bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) {
+            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
                 return true;
             }
             if (formula.isGloballyFormula()) {
                 return true;
             }
             if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
             }
             if (formula.isConditionalPathFormula()) {
                 storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
@@ -111,9 +111,9 @@ namespace storm {
         }
         
         template<typename SparseDtmcModelType>
-        std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+        std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
             std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);
             return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
index 77217a3ac..acc7d9283 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
@@ -27,7 +27,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
             
         private:
diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
index 710d926a7..a7a56a890 100644
--- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
@@ -39,11 +39,11 @@ namespace storm {
         template<typename SparseMdpModelType>
         bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) {
+            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
                 return true;
             }
             if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
             }
             if (formula.isGloballyFormula()) {
                 return true;
@@ -140,10 +140,10 @@ namespace storm {
         }
                 
         template<typename SparseMdpModelType>
-        std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
             STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
             std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory);
             return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
index 1a0d85b2c..37cd6ef5b 100644
--- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
@@ -25,7 +25,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
             
         private:
diff --git a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
index 0053d6b77..2394a3176 100644
--- a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
@@ -32,11 +32,11 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool SymbolicDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) {
+            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
                 return true;
             }
             if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
             }
             if (formula.isGloballyFormula()) {
                 return true;
@@ -102,9 +102,9 @@ namespace storm {
         }
         
         template<storm::dd::DdType DdType, typename ValueType>
-        std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+        std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
             storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
             return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType>>(new SymbolicQuantitativeCheckResult<DdType>(this->getModel().getReachableStates(), numericResult));
diff --git a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h
index a7968a56a..3472ee1b0 100644
--- a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h
@@ -21,7 +21,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             
         protected:
             storm::models::symbolic::Dtmc<DdType, ValueType> const& getModel() const override;
diff --git a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
index 30891afdf..9b74594dc 100644
--- a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
@@ -32,11 +32,11 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool SymbolicMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) {
+            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
                 return true;
             }
             if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
             }
             if (formula.isGloballyFormula()) {
                 return true;
@@ -102,10 +102,10 @@ namespace storm {
         }
         
         template<storm::dd::DdType DdType, typename ValueType>
-        std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
             STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
             return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
         }
diff --git a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h
index 1baca69da..488971353 100644
--- a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h
@@ -23,7 +23,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             
             protected:
             storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override;
diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
index 554eba5e3..98afe49a1 100644
--- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
+++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
@@ -83,9 +83,9 @@ namespace storm {
         bool SparseDtmcEliminationModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
             if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
             } else if (formula.isRewardOperatorFormula()) {
-                return this->canHandle(checkTask.replaceFormula(formula.asRewardOperatorFormula().getSubformula()));
+                return this->canHandle(checkTask.substituteFormula(formula.asRewardOperatorFormula().getSubformula()));
             } else if (formula.isUntilFormula() || formula.isEventuallyFormula()) {
                 if (formula.isUntilFormula()) {
                     storm::logic::UntilFormula const& untilFormula = formula.asUntilFormula();
@@ -103,11 +103,6 @@ namespace storm {
                 if (boundedUntilFormula.getLeftSubformula().isPropositionalFormula() && boundedUntilFormula.getRightSubformula().isPropositionalFormula()) {
                     return true;
                 }
-            } else if (formula.isReachabilityRewardFormula()) {
-                storm::logic::ReachabilityRewardFormula const& reachabilityRewardFormula = formula.asReachabilityRewardFormula();
-                if (reachabilityRewardFormula.getSubformula().isPropositionalFormula()) {
-                    return true;
-                }
             } else if (formula.isConditionalPathFormula()) {
                 storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
                 if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) {
@@ -579,11 +574,11 @@ namespace storm {
         }
         
         template<typename SparseDtmcModelType>
-        std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) {
-            storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
+            storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
             
             // Retrieve the appropriate bitvectors by model checking the subformulas.
-            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
+            std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
             storm::storage::BitVector phiStates(this->getModel().getNumberOfStates(), true);
             storm::storage::BitVector const& psiStates = subResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector();
             
diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
index 809522260..af5b464be 100644
--- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
+++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
@@ -26,7 +26,7 @@ namespace storm {
             virtual bool canHandle(CheckTask<storm::logic::Formula> const& checkTask) const override;
             virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp
index c919280b4..4bf036e4f 100644
--- a/src/parser/FormulaParser.cpp
+++ b/src/parser/FormulaParser.cpp
@@ -129,7 +129,6 @@ namespace storm {
             
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardPathFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> cumulativeRewardFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> reachabilityRewardFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> instantaneousRewardFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> longRunAverageRewardFormula;
             
@@ -139,7 +138,6 @@ namespace storm {
             // Methods that actually create the expression objects.
             std::shared_ptr<storm::logic::Formula> createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
             std::shared_ptr<storm::logic::Formula> createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
-            std::shared_ptr<storm::logic::Formula> createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const;
             std::shared_ptr<storm::logic::Formula> createLongRunAverageRewardFormula() const;
             std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
             std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
@@ -255,10 +253,7 @@ namespace storm {
             cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
             cumulativeRewardFormula.name("cumulative reward formula");
             
-            reachabilityRewardFormula = (qi::lit("F") > stateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createReachabilityRewardFormula, phoenix::ref(*this), qi::_1)];
-            reachabilityRewardFormula.name("reachability reward formula");
-            
-            rewardPathFormula = reachabilityRewardFormula | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula;
+            rewardPathFormula = eventuallyFormula | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula;
             rewardPathFormula.name("reward path formula");
             
             expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)];
@@ -382,7 +377,6 @@ namespace storm {
             qi::on_error<qi::fail>(labelFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(expressionFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(rewardPathFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
-            qi::on_error<qi::fail>(reachabilityRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(cumulativeRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
             qi::on_error<qi::fail>(instantaneousRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
         }
@@ -411,10 +405,6 @@ namespace storm {
             }
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const {
-            return std::shared_ptr<storm::logic::Formula>(new storm::logic::ReachabilityRewardFormula(stateFormula));
-        }
-        
         std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createLongRunAverageRewardFormula() const {
             return std::shared_ptr<storm::logic::Formula>(new storm::logic::LongRunAverageRewardFormula());
         }
diff --git a/src/storage/bisimulation/BisimulationDecomposition.cpp b/src/storage/bisimulation/BisimulationDecomposition.cpp
index c8c47c5a8..902a69288 100644
--- a/src/storage/bisimulation/BisimulationDecomposition.cpp
+++ b/src/storage/bisimulation/BisimulationDecomposition.cpp
@@ -122,11 +122,6 @@ namespace storm {
                 if (rightSubformula->isPropositionalFormula()) {
                     measureDrivenInitialPartition = true;
                 }
-            } else if (newFormula->isReachabilityRewardFormula()) {
-                rightSubformula = newFormula->asReachabilityRewardFormula().getSubformula().asSharedPointer();
-                if (rightSubformula->isPropositionalFormula()) {
-                    measureDrivenInitialPartition = true;
-                }
             }
             
             if (measureDrivenInitialPartition) {

From be8c65525ef1e837a1579e9b8b80a61161c6efff Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 16 Feb 2016 21:12:55 +0100
Subject: [PATCH 02/23] introduced some methods to query formula type

Former-commit-id: 9ecc13566de3141c424483b3e06094889c5ae0de
---
 src/logic/AtomicExpressionFormula.cpp         |  4 +++
 src/logic/AtomicExpressionFormula.h           |  1 +
 src/logic/AtomicLabelFormula.cpp              |  4 +++
 src/logic/AtomicLabelFormula.h                |  1 +
 src/logic/BinaryPathFormula.cpp               |  4 +++
 src/logic/BinaryPathFormula.h                 |  1 +
 src/logic/BinaryStateFormula.cpp              |  4 +++
 src/logic/BinaryStateFormula.h                |  1 +
 src/logic/BooleanLiteralFormula.cpp           |  4 +++
 src/logic/BooleanLiteralFormula.h             |  1 +
 src/logic/BoundedUntilFormula.cpp             |  4 +++
 src/logic/BoundedUntilFormula.h               |  1 +
 src/logic/ConditionalPathFormula.cpp          | 14 +++++++-
 src/logic/ConditionalPathFormula.h            |  8 ++++-
 src/logic/CumulativeRewardFormula.cpp         |  4 +++
 src/logic/CumulativeRewardFormula.h           |  1 +
 src/logic/EventuallyFormula.cpp               | 10 ++++--
 src/logic/EventuallyFormula.h                 |  5 ++-
 src/logic/ExpectedTimeOperatorFormula.cpp     |  4 +++
 src/logic/ExpectedTimeOperatorFormula.h       |  1 +
 src/logic/Formula.cpp                         | 32 +++++++++++++++++++
 src/logic/Formula.h                           |  8 +++++
 src/logic/InstantaneousRewardFormula.cpp      |  4 +++
 src/logic/InstantaneousRewardFormula.h        |  1 +
 src/logic/LongRunAverageOperatorFormula.cpp   |  4 +++
 src/logic/LongRunAverageOperatorFormula.h     |  1 +
 src/logic/LongRunAverageRewardFormula.cpp     |  4 +++
 src/logic/LongRunAverageRewardFormula.h       |  1 +
 src/logic/ProbabilityOperatorFormula.cpp      |  4 +++
 src/logic/ProbabilityOperatorFormula.h        |  1 +
 src/logic/RewardOperatorFormula.cpp           |  5 ++-
 src/logic/RewardOperatorFormula.h             |  2 +-
 src/logic/UnaryPathFormula.cpp                |  4 +++
 src/logic/UnaryPathFormula.h                  |  1 +
 src/logic/UnaryStateFormula.cpp               |  4 +++
 src/logic/UnaryStateFormula.h                 |  1 +
 .../csl/HybridCtmcCslModelChecker.cpp         |  2 +-
 src/parser/FormulaParser.cpp                  | 28 ++++++++--------
 38 files changed, 159 insertions(+), 25 deletions(-)

diff --git a/src/logic/AtomicExpressionFormula.cpp b/src/logic/AtomicExpressionFormula.cpp
index 6747d2ab5..35c7149b0 100644
--- a/src/logic/AtomicExpressionFormula.cpp
+++ b/src/logic/AtomicExpressionFormula.cpp
@@ -13,6 +13,10 @@ namespace storm {
         bool AtomicExpressionFormula::isPctlStateFormula() const {
             return true;
         }
+        
+        bool AtomicExpressionFormula::isPctlWithConditionalStateFormula() const {
+            return true;
+        }
                 
         bool AtomicExpressionFormula::isLtlFormula() const {
             return true;
diff --git a/src/logic/AtomicExpressionFormula.h b/src/logic/AtomicExpressionFormula.h
index f054c9e42..2b2e36dd5 100644
--- a/src/logic/AtomicExpressionFormula.h
+++ b/src/logic/AtomicExpressionFormula.h
@@ -16,6 +16,7 @@ namespace storm {
             virtual bool isAtomicExpressionFormula() const override;
             
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool isPropositionalFormula() const override;
             
diff --git a/src/logic/AtomicLabelFormula.cpp b/src/logic/AtomicLabelFormula.cpp
index 0555ff56a..36c00eb23 100644
--- a/src/logic/AtomicLabelFormula.cpp
+++ b/src/logic/AtomicLabelFormula.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return true;
         }
     
+        bool AtomicLabelFormula::isPctlWithConditionalStateFormula() const {
+            return true;
+        }
+        
         bool AtomicLabelFormula::isLtlFormula() const {
             return true;
         }
diff --git a/src/logic/AtomicLabelFormula.h b/src/logic/AtomicLabelFormula.h
index 8cd2f51f1..3d326c211 100644
--- a/src/logic/AtomicLabelFormula.h
+++ b/src/logic/AtomicLabelFormula.h
@@ -18,6 +18,7 @@ namespace storm {
             virtual bool isAtomicLabelFormula() const override;
 
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool isPropositionalFormula() const override;
             
diff --git a/src/logic/BinaryPathFormula.cpp b/src/logic/BinaryPathFormula.cpp
index 949dbf378..5075894c4 100644
--- a/src/logic/BinaryPathFormula.cpp
+++ b/src/logic/BinaryPathFormula.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
         }
         
+        bool BinaryPathFormula::isPctlWithConditionalPathFormula() const {
+            return this->getLeftSubformula().isPctlWithConditionalPathFormula() && this->getRightSubformula().isPctlWithConditionalPathFormula();
+        }
+        
         bool BinaryPathFormula::isCslPathFormula() const {
             return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
         }
diff --git a/src/logic/BinaryPathFormula.h b/src/logic/BinaryPathFormula.h
index 928d21728..14d162926 100644
--- a/src/logic/BinaryPathFormula.h
+++ b/src/logic/BinaryPathFormula.h
@@ -18,6 +18,7 @@ namespace storm {
             virtual bool isBinaryPathFormula() const override;
             
             virtual bool isPctlPathFormula() const override;
+            virtual bool isPctlWithConditionalPathFormula() const override;
             virtual bool isCslPathFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool containsBoundedUntilFormula() const override;
diff --git a/src/logic/BinaryStateFormula.cpp b/src/logic/BinaryStateFormula.cpp
index 6993707ad..bcaa2d39b 100644
--- a/src/logic/BinaryStateFormula.cpp
+++ b/src/logic/BinaryStateFormula.cpp
@@ -13,6 +13,10 @@ namespace storm {
         bool BinaryStateFormula::isPctlStateFormula() const {
             return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
         }
+        
+        bool BinaryStateFormula::isPctlWithConditionalStateFormula() const {
+            return this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula();
+        }
 
         bool BinaryStateFormula::isCslStateFormula() const {
             return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
diff --git a/src/logic/BinaryStateFormula.h b/src/logic/BinaryStateFormula.h
index a0fcbc9d1..c259aa759 100644
--- a/src/logic/BinaryStateFormula.h
+++ b/src/logic/BinaryStateFormula.h
@@ -16,6 +16,7 @@ namespace storm {
             virtual bool isBinaryStateFormula() const override;
 
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool isCslStateFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool containsBoundedUntilFormula() const override;
diff --git a/src/logic/BooleanLiteralFormula.cpp b/src/logic/BooleanLiteralFormula.cpp
index aa78a6772..d021bbc64 100644
--- a/src/logic/BooleanLiteralFormula.cpp
+++ b/src/logic/BooleanLiteralFormula.cpp
@@ -18,6 +18,10 @@ namespace storm {
             return true;
         }
         
+        bool BooleanLiteralFormula::isPctlWithConditionalStateFormula() const {
+            return true;
+        }
+        
         bool BooleanLiteralFormula::isLtlFormula() const {
             return true;
         }
diff --git a/src/logic/BooleanLiteralFormula.h b/src/logic/BooleanLiteralFormula.h
index d8df08651..1283fde71 100644
--- a/src/logic/BooleanLiteralFormula.h
+++ b/src/logic/BooleanLiteralFormula.h
@@ -18,6 +18,7 @@ namespace storm {
             virtual bool isFalseFormula() const override;
 
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool isPropositionalFormula() const override;
             
diff --git a/src/logic/BoundedUntilFormula.cpp b/src/logic/BoundedUntilFormula.cpp
index 7c29c579b..9a1f867e1 100644
--- a/src/logic/BoundedUntilFormula.cpp
+++ b/src/logic/BoundedUntilFormula.cpp
@@ -38,6 +38,10 @@ namespace storm {
             return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
         }
         
+        bool BoundedUntilFormula::isPctlWithConditionalPathFormula() const {
+            return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula();
+        }
+        
         bool BoundedUntilFormula::isCslPathFormula() const {
             return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
         }
diff --git a/src/logic/BoundedUntilFormula.h b/src/logic/BoundedUntilFormula.h
index 7da7e70f6..bc14d8def 100644
--- a/src/logic/BoundedUntilFormula.h
+++ b/src/logic/BoundedUntilFormula.h
@@ -23,6 +23,7 @@ namespace storm {
             uint_fast64_t getDiscreteTimeBound() const;
             
             virtual bool isValidProbabilityPathFormula() const override;
+            virtual bool isPctlWithConditionalPathFormula() const override;
             virtual bool isPctlPathFormula() const override;
             virtual bool isCslPathFormula() const override;
 
diff --git a/src/logic/ConditionalPathFormula.cpp b/src/logic/ConditionalPathFormula.cpp
index 8ef461e35..676a83185 100644
--- a/src/logic/ConditionalPathFormula.cpp
+++ b/src/logic/ConditionalPathFormula.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace logic {
-        ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) {
+        ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula) : BinaryPathFormula(leftSubformula, rightSubformula), isRewardFormula(isRewardFormula) {
             // Intentionally left empty.
         }
         
@@ -14,6 +14,18 @@ namespace storm {
             return true;
         }
         
+        bool ConditionalPathFormula::isPctlWithConditionalPathFormula() const {
+            return this->getLeftSubformula().isPctlPathFormula() && this->getRightSubformula().isPctlPathFormula();
+        }
+        
+        bool ConditionalPathFormula::isRewardPathFormula() const {
+            return this->isRewardFormula && this->isValidRewardPathFormula();
+        }
+        
+        bool ConditionalPathFormula::isValidRewardPathFormula() const {
+            return this->getLeftSubformula().isRewardPathFormula() && !this->getLeftSubformula().isConditionalPathFormula() && this->getRightSubformula().isPctlPathFormula();
+        }
+        
         std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
         }
diff --git a/src/logic/ConditionalPathFormula.h b/src/logic/ConditionalPathFormula.h
index a3e12e20f..94053606b 100644
--- a/src/logic/ConditionalPathFormula.h
+++ b/src/logic/ConditionalPathFormula.h
@@ -7,18 +7,24 @@ namespace storm {
     namespace logic {
         class ConditionalPathFormula : public BinaryPathFormula {
         public:
-            ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula);
+            ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula = false);
             
             virtual ~ConditionalPathFormula() {
                 // Intentionally left empty.
             }
             
+            virtual bool isPctlWithConditionalPathFormula() const override;
+            virtual bool isRewardPathFormula() const override;
             virtual bool isConditionalPathFormula() const override;
             virtual bool isValidProbabilityPathFormula() const override;
+            virtual bool isValidRewardPathFormula() const override;
 
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
+            
+        private:
+            bool isRewardFormula;
         };
     }
 }
diff --git a/src/logic/CumulativeRewardFormula.cpp b/src/logic/CumulativeRewardFormula.cpp
index 3f53c2e9d..2a00c04f3 100644
--- a/src/logic/CumulativeRewardFormula.cpp
+++ b/src/logic/CumulativeRewardFormula.cpp
@@ -10,6 +10,10 @@ namespace storm {
             // Intentionally left empty.
         }
         
+        bool CumulativeRewardFormula::isRewardPathFormula() const {
+            return true;
+        }
+        
         bool CumulativeRewardFormula::isCumulativeRewardFormula() const {
             return true;
         }
diff --git a/src/logic/CumulativeRewardFormula.h b/src/logic/CumulativeRewardFormula.h
index 4ebf08cd4..0192a8a49 100644
--- a/src/logic/CumulativeRewardFormula.h
+++ b/src/logic/CumulativeRewardFormula.h
@@ -17,6 +17,7 @@ namespace storm {
                 // Intentionally left empty.
             }
             
+            virtual bool isRewardPathFormula() const override;
             virtual bool isCumulativeRewardFormula() const override;
             virtual bool isValidRewardPathFormula() const override;
 
diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp
index a25d12b33..8b09281cd 100644
--- a/src/logic/EventuallyFormula.cpp
+++ b/src/logic/EventuallyFormula.cpp
@@ -2,7 +2,7 @@
 
 namespace storm {
     namespace logic {
-        EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) {
+        EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula) : UnaryPathFormula(subformula), isRewardFormula(isRewardFormula) {
             // Intentionally left empty.
         }
         
@@ -10,12 +10,16 @@ namespace storm {
             return true;
         }
         
+        bool EventuallyFormula::isRewardPathFormula() const {
+            return isRewardFormula;
+        }
+        
         bool EventuallyFormula::isValidProbabilityPathFormula() const {
-            return true;
+            return !isRewardFormula;
         }
         
         bool EventuallyFormula::isValidRewardPathFormula() const {
-            return true;
+            return isRewardFormula;
         }
         
         std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h
index a488eb443..3b121d320 100644
--- a/src/logic/EventuallyFormula.h
+++ b/src/logic/EventuallyFormula.h
@@ -7,13 +7,14 @@ namespace storm {
     namespace logic {
         class EventuallyFormula : public UnaryPathFormula {
         public:
-            EventuallyFormula(std::shared_ptr<Formula const> const& subformula);
+            EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula = false);
             
             virtual ~EventuallyFormula() {
                 // Intentionally left empty.
             }
             
             virtual bool isEventuallyFormula() const override;
+            virtual bool isRewardPathFormula() const override;
             virtual bool isValidProbabilityPathFormula() const override;
             virtual bool isValidRewardPathFormula() const override;
 
@@ -21,6 +22,8 @@ namespace storm {
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
 
+        private:
+            bool isRewardFormula;
         };
     }
 }
diff --git a/src/logic/ExpectedTimeOperatorFormula.cpp b/src/logic/ExpectedTimeOperatorFormula.cpp
index ed21be228..8165710a1 100644
--- a/src/logic/ExpectedTimeOperatorFormula.cpp
+++ b/src/logic/ExpectedTimeOperatorFormula.cpp
@@ -26,6 +26,10 @@ namespace storm {
             return this->getSubformula().isPctlStateFormula();
         }
         
+        bool ExpectedTimeOperatorFormula::isPctlWithConditionalStateFormula() const {
+            return this->getSubformula().isPctlWithConditionalStateFormula();
+        }
+        
         bool ExpectedTimeOperatorFormula::containsProbabilityOperator() const {
             return this->getSubformula().containsProbabilityOperator();
         }
diff --git a/src/logic/ExpectedTimeOperatorFormula.h b/src/logic/ExpectedTimeOperatorFormula.h
index 5702610c2..162fb39f8 100644
--- a/src/logic/ExpectedTimeOperatorFormula.h
+++ b/src/logic/ExpectedTimeOperatorFormula.h
@@ -20,6 +20,7 @@ namespace storm {
             virtual bool isExpectedTimeOperatorFormula() const override;
             
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool containsProbabilityOperator() const override;
             virtual bool containsNestedProbabilityOperators() const override;
             
diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp
index e3fa84c74..9f9151b84 100644
--- a/src/logic/Formula.cpp
+++ b/src/logic/Formula.cpp
@@ -111,6 +111,22 @@ namespace storm {
             return false;
         }
         
+        bool Formula::isPctlFormula() const {
+            return this->isPctlStateFormula() || this->isPctlPathFormula();
+        }
+        
+        bool Formula::isPctlWithConditionalFormula() const {
+            return this->isPctlWithConditionalStateFormula() || this->isPctlWithConditionalPathFormula();
+        }
+        
+        bool Formula::isRewardFormula() const {
+            return this->isRewardStateFormula() || this->isRewardPathFormula();
+        }
+        
+        bool Formula::isCslFormula() const {
+            return this->isCslStateFormula() || this->isCslPathFormula();
+        }
+        
         bool Formula::isPctlPathFormula() const {
             return false;
         }
@@ -119,6 +135,14 @@ namespace storm {
             return false;
         }
         
+        bool Formula::isPctlWithConditionalPathFormula() const {
+            return false;
+        }
+        
+        bool Formula::isPctlWithConditionalStateFormula() const {
+            return false;
+        }
+        
         bool Formula::isCslPathFormula() const {
             return this->isPctlPathFormula();
         }
@@ -127,6 +151,14 @@ namespace storm {
             return this->isPctlStateFormula();
         }
         
+        bool Formula::isRewardPathFormula() const {
+            return false;
+        }
+        
+        bool Formula::isRewardStateFormula() const {
+            return false;
+        }
+        
         bool Formula::isPltlFormula() const {
             return false;
         }
diff --git a/src/logic/Formula.h b/src/logic/Formula.h
index 2ea234449..cf4333eb4 100644
--- a/src/logic/Formula.h
+++ b/src/logic/Formula.h
@@ -79,10 +79,18 @@ namespace storm {
             virtual bool isRewardOperatorFormula() const;
             virtual bool isOperatorFormula() const;
 
+            bool isPctlFormula() const;
+            bool isPctlWithConditionalFormula() const;
+            bool isRewardFormula() const;
+            bool isCslFormula() const;
             virtual bool isPctlPathFormula() const;
             virtual bool isPctlStateFormula() const;
+            virtual bool isPctlWithConditionalPathFormula() const;
+            virtual bool isPctlWithConditionalStateFormula() const;
             virtual bool isCslPathFormula() const;
             virtual bool isCslStateFormula() const;
+            virtual bool isRewardPathFormula() const;
+            virtual bool isRewardStateFormula() const;
             virtual bool isPltlFormula() const;
             virtual bool isLtlFormula() const;
             virtual bool isPropositionalFormula() const;
diff --git a/src/logic/InstantaneousRewardFormula.cpp b/src/logic/InstantaneousRewardFormula.cpp
index 77efb5705..7289f18e9 100644
--- a/src/logic/InstantaneousRewardFormula.cpp
+++ b/src/logic/InstantaneousRewardFormula.cpp
@@ -18,6 +18,10 @@ namespace storm {
             return true;
         }
         
+        bool InstantaneousRewardFormula::isRewardPathFormula() const {
+            return true;
+        }
+        
         bool InstantaneousRewardFormula::hasDiscreteTimeBound() const {
             return timeBound.which() == 0;
         }
diff --git a/src/logic/InstantaneousRewardFormula.h b/src/logic/InstantaneousRewardFormula.h
index c895c5b39..967f03a2b 100644
--- a/src/logic/InstantaneousRewardFormula.h
+++ b/src/logic/InstantaneousRewardFormula.h
@@ -17,6 +17,7 @@ namespace storm {
                 // Intentionally left empty.
             }
             
+            virtual bool isRewardPathFormula() const override;
             virtual bool isInstantaneousRewardFormula() const override;
             virtual bool isValidRewardPathFormula() const override;
 
diff --git a/src/logic/LongRunAverageOperatorFormula.cpp b/src/logic/LongRunAverageOperatorFormula.cpp
index cfeb30692..1563dc67e 100644
--- a/src/logic/LongRunAverageOperatorFormula.cpp
+++ b/src/logic/LongRunAverageOperatorFormula.cpp
@@ -26,6 +26,10 @@ namespace storm {
             return this->getSubformula().isPctlStateFormula();
         }
         
+        bool LongRunAverageOperatorFormula::isPctlWithConditionalStateFormula() const {
+            return this->getSubformula().isPctlWithConditionalStateFormula();
+        }
+        
         bool LongRunAverageOperatorFormula::containsProbabilityOperator() const {
             return this->getSubformula().containsProbabilityOperator();
         }
diff --git a/src/logic/LongRunAverageOperatorFormula.h b/src/logic/LongRunAverageOperatorFormula.h
index 89e119f48..85eb9f969 100644
--- a/src/logic/LongRunAverageOperatorFormula.h
+++ b/src/logic/LongRunAverageOperatorFormula.h
@@ -20,6 +20,7 @@ namespace storm {
             virtual bool isLongRunAverageOperatorFormula() const override;
             
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool containsProbabilityOperator() const override;
             virtual bool containsNestedProbabilityOperators() const override;
             
diff --git a/src/logic/LongRunAverageRewardFormula.cpp b/src/logic/LongRunAverageRewardFormula.cpp
index 7bc064c1e..9d9dc898d 100644
--- a/src/logic/LongRunAverageRewardFormula.cpp
+++ b/src/logic/LongRunAverageRewardFormula.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return true;
         }
         
+        bool LongRunAverageRewardFormula::isRewardPathFormula() const {
+            return true;
+        }
+        
         std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::shared_ptr<Formula>(new LongRunAverageRewardFormula());
         }
diff --git a/src/logic/LongRunAverageRewardFormula.h b/src/logic/LongRunAverageRewardFormula.h
index aa4d3f424..929a6f3c8 100644
--- a/src/logic/LongRunAverageRewardFormula.h
+++ b/src/logic/LongRunAverageRewardFormula.h
@@ -13,6 +13,7 @@ namespace storm {
                 // Intentionally left empty.
             }
             
+            virtual bool isRewardPathFormula() const override;
             virtual bool isLongRunAverageRewardFormula() const override;
             virtual bool isValidRewardPathFormula() const override;
 
diff --git a/src/logic/ProbabilityOperatorFormula.cpp b/src/logic/ProbabilityOperatorFormula.cpp
index 1f4615556..cb584b034 100644
--- a/src/logic/ProbabilityOperatorFormula.cpp
+++ b/src/logic/ProbabilityOperatorFormula.cpp
@@ -26,6 +26,10 @@ namespace storm {
             return this->getSubformula().isPctlPathFormula();
         }
         
+        bool ProbabilityOperatorFormula::isPctlWithConditionalStateFormula() const {
+            return this->getSubformula().isPctlWithConditionalPathFormula();
+        }
+        
         bool ProbabilityOperatorFormula::isCslStateFormula() const {
             return this->getSubformula().isCslPathFormula();
         }
diff --git a/src/logic/ProbabilityOperatorFormula.h b/src/logic/ProbabilityOperatorFormula.h
index 8bae11548..163e05f58 100644
--- a/src/logic/ProbabilityOperatorFormula.h
+++ b/src/logic/ProbabilityOperatorFormula.h
@@ -18,6 +18,7 @@ namespace storm {
             }
             
             virtual bool isPctlStateFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool isCslStateFormula() const override;
             virtual bool isPltlFormula() const override;
             virtual bool containsProbabilityOperator() const override;
diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp
index 1e5390830..0eea0eedc 100644
--- a/src/logic/RewardOperatorFormula.cpp
+++ b/src/logic/RewardOperatorFormula.cpp
@@ -22,9 +22,8 @@ namespace storm {
             return true;
         }
         
-        bool RewardOperatorFormula::isPctlStateFormula() const {
-            Formula const& subformula = this->getSubformula();
-            return subformula.isEventuallyFormula() || subformula.isCumulativeRewardFormula() || subformula.isInstantaneousRewardFormula();
+        bool RewardOperatorFormula::isRewardStateFormula() const {
+            return this->getSubformula().isRewardPathFormula();
         }
         
         bool RewardOperatorFormula::containsRewardOperator() const {
diff --git a/src/logic/RewardOperatorFormula.h b/src/logic/RewardOperatorFormula.h
index 9e90ef01f..0cbfe955e 100644
--- a/src/logic/RewardOperatorFormula.h
+++ b/src/logic/RewardOperatorFormula.h
@@ -19,8 +19,8 @@ namespace storm {
             }
             
             virtual bool isRewardOperatorFormula() const override;
+            virtual bool isRewardStateFormula() const override;
 
-            virtual bool isPctlStateFormula() const override;
             virtual bool containsRewardOperator() const override;
             virtual bool containsNestedRewardOperators() const override;
             
diff --git a/src/logic/UnaryPathFormula.cpp b/src/logic/UnaryPathFormula.cpp
index d961f1612..01ccadde8 100644
--- a/src/logic/UnaryPathFormula.cpp
+++ b/src/logic/UnaryPathFormula.cpp
@@ -14,6 +14,10 @@ namespace storm {
             return this->getSubformula().isPctlStateFormula();
         }
         
+        bool UnaryPathFormula::isPctlWithConditionalPathFormula() const {
+            return this->getSubformula().isPctlWithConditionalStateFormula();
+        }
+        
         bool UnaryPathFormula::isLtlFormula() const {
             return this->getSubformula().isLtlFormula();
         }
diff --git a/src/logic/UnaryPathFormula.h b/src/logic/UnaryPathFormula.h
index 8d168585c..be60edbd9 100644
--- a/src/logic/UnaryPathFormula.h
+++ b/src/logic/UnaryPathFormula.h
@@ -18,6 +18,7 @@ namespace storm {
             virtual bool isUnaryPathFormula() const override;
             
             virtual bool isPctlPathFormula() const override;
+            virtual bool isPctlWithConditionalPathFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool containsBoundedUntilFormula() const override;
             virtual bool containsNextFormula() const override;
diff --git a/src/logic/UnaryStateFormula.cpp b/src/logic/UnaryStateFormula.cpp
index 4bf651aa1..a57b86b1e 100644
--- a/src/logic/UnaryStateFormula.cpp
+++ b/src/logic/UnaryStateFormula.cpp
@@ -18,6 +18,10 @@ namespace storm {
             return this->getSubformula().isPctlStateFormula();
         }
         
+        bool UnaryStateFormula::isPctlWithConditionalStateFormula() const {
+            return this->getSubformula().isPctlWithConditionalStateFormula();
+        }
+
         bool UnaryStateFormula::isLtlFormula() const {
             return this->getSubformula().isLtlFormula();
         }
diff --git a/src/logic/UnaryStateFormula.h b/src/logic/UnaryStateFormula.h
index 745687e6b..8b5539a88 100644
--- a/src/logic/UnaryStateFormula.h
+++ b/src/logic/UnaryStateFormula.h
@@ -16,6 +16,7 @@ namespace storm {
             virtual bool isUnaryStateFormula() const override;
 
             virtual bool isPropositionalFormula() const override;
+            virtual bool isPctlWithConditionalStateFormula() const override;
             virtual bool isPctlStateFormula() const override;
             virtual bool isLtlFormula() const override;
             virtual bool containsBoundedUntilFormula() const override;
diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
index 412ab836c..c6b7c9d1e 100644
--- a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
+++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
@@ -25,7 +25,7 @@ namespace storm {
         template<storm::dd::DdType DdType, class ValueType>
         bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslStateFormula() || formula.isCslPathFormula();
+            return formula.isCslFormula() || formula.isRewardFormula();
         }
                 
         template<storm::dd::DdType DdType, class ValueType>
diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp
index 4bf036e4f..1298b3fa2 100644
--- a/src/parser/FormulaParser.cpp
+++ b/src/parser/FormulaParser.cpp
@@ -120,8 +120,8 @@ namespace storm {
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula;
             
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> conditionalFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> eventuallyFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> conditionalFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> eventuallyFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula;
@@ -142,11 +142,11 @@ namespace storm {
             std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
             std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
             std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const;
-            std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const;
+            std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
-            std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const;
+            std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const;
             std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const;
             std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
@@ -253,7 +253,7 @@ namespace storm {
             cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
             cumulativeRewardFormula.name("cumulative reward formula");
             
-            rewardPathFormula = eventuallyFormula | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula;
+            rewardPathFormula = eventuallyFormula(true) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(true);
             rewardPathFormula.name("reward path formula");
             
             expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)];
@@ -277,7 +277,7 @@ namespace storm {
             notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)];
             notStateFormula.name("negation formula");
             
-            eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_r1, qi::_2)];
             eventuallyFormula.name("eventually formula");
             
             globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)];
@@ -286,19 +286,19 @@ namespace storm {
             nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)];
             nextFormula.name("next formula");
             
-            pathFormulaWithoutUntil = eventuallyFormula | globallyFormula | nextFormula | stateFormula;
+            pathFormulaWithoutUntil = eventuallyFormula(false) | globallyFormula | nextFormula | stateFormula;
             pathFormulaWithoutUntil.name("path formula");
             
             untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
             untilFormula.name("until formula");
             
-            conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1)];
+            conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_r1)];
             conditionalFormula.name("conditional formula");
             
             timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") >  qi::uint_)[qi::_val = qi::_1];
             timeBound.name("time bound");
             
-            pathFormula = conditionalFormula;
+            pathFormula = conditionalFormula(false);
             pathFormula.name("path formula");
             
             operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorInformation, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
@@ -313,7 +313,7 @@ namespace storm {
             rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
             rewardOperator.name("reward operator");
             
-            expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(true) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
             expectedTimeOperator.name("expected time operator");
             
             probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
@@ -422,7 +422,7 @@ namespace storm {
             return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label));
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const {
+        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const {
             if (timeBound) {
                 if (timeBound.get().which() == 0) {
                     std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get());
@@ -431,7 +431,7 @@ namespace storm {
                     return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, static_cast<uint_fast64_t>(boost::get<uint_fast64_t>(timeBound.get()))));
                 }
             } else {
-                return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula));
+                return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula, reward));
             }
         }
         
@@ -456,8 +456,8 @@ namespace storm {
             }
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const {
-            return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula));
+        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const {
+            return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula, reward));
         }
         
         std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> FormulaParserGrammar::createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const {

From 2604df54ec2077a45353df7baed7e521c5f96c9f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 17 Feb 2016 18:40:56 +0100
Subject: [PATCH 03/23] more refactoring of formula classes: in particular
 fragment checking

Former-commit-id: 544c5f953fc496f4fce8f002270fa0c0380992dc
---
 src/builder/DdPrismModelBuilder.cpp         |   6 +-
 src/builder/ExplicitPrismModelBuilder.cpp   |   6 +-
 src/logic/AtomicExpressionFormula.cpp       |  18 +-
 src/logic/AtomicExpressionFormula.h         |   5 +-
 src/logic/AtomicLabelFormula.cpp            |  18 +-
 src/logic/AtomicLabelFormula.h              |   5 +-
 src/logic/BinaryBooleanStateFormula.cpp     |   6 +-
 src/logic/BinaryBooleanStateFormula.h       |   2 +-
 src/logic/BinaryPathFormula.cpp             |  42 +---
 src/logic/BinaryPathFormula.h               |  11 --
 src/logic/BinaryStateFormula.cpp            |  42 +---
 src/logic/BinaryStateFormula.h              |  11 --
 src/logic/BooleanLiteralFormula.cpp         |  26 +--
 src/logic/BooleanLiteralFormula.h           |   7 +-
 src/logic/BoundedUntilFormula.cpp           |  26 +--
 src/logic/BoundedUntilFormula.h             |   9 +-
 src/logic/ConditionalFormula.cpp            |  42 ++++
 src/logic/ConditionalFormula.h              |  38 ++++
 src/logic/ConditionalPathFormula.cpp        |  40 ----
 src/logic/ConditionalPathFormula.h          |  32 ---
 src/logic/CumulativeRewardFormula.cpp       |  10 +-
 src/logic/CumulativeRewardFormula.h         |   7 +-
 src/logic/EventuallyFormula.cpp             |  28 ++-
 src/logic/EventuallyFormula.h               |  14 +-
 src/logic/ExpectedTimeOperatorFormula.cpp   |  18 +-
 src/logic/ExpectedTimeOperatorFormula.h     |   9 +-
 src/logic/Formula.cpp                       | 108 ++--------
 src/logic/Formula.h                         | 107 ++++------
 src/logic/FormulaVisitor.h                  |  36 ++++
 src/logic/Formulas.h                        |   2 +-
 src/logic/FormulasForwardDeclarations.h     |  36 ++++
 src/logic/FragmentChecker.cpp               | 118 +++++++++++
 src/logic/FragmentChecker.h                 |  39 ++++
 src/logic/FragmentSpecification.cpp         | 209 ++++++++++++++++++++
 src/logic/FragmentSpecification.h           | 112 +++++++++++
 src/logic/GloballyFormula.cpp               |   8 +-
 src/logic/GloballyFormula.h                 |   4 +-
 src/logic/InstantaneousRewardFormula.cpp    |   8 +-
 src/logic/InstantaneousRewardFormula.h      |   6 +-
 src/logic/LongRunAverageOperatorFormula.cpp |  18 +-
 src/logic/LongRunAverageOperatorFormula.h   |   5 +-
 src/logic/LongRunAverageRewardFormula.cpp   |   8 +-
 src/logic/LongRunAverageRewardFormula.h     |   5 +-
 src/logic/NextFormula.cpp                   |   8 +-
 src/logic/NextFormula.h                     |   4 +-
 src/logic/ProbabilityOperatorFormula.cpp    |  28 +--
 src/logic/ProbabilityOperatorFormula.h      |   9 +-
 src/logic/RewardOperatorFormula.cpp         |  18 +-
 src/logic/RewardOperatorFormula.h           |   6 +-
 src/logic/UnaryBooleanStateFormula.cpp      |   6 +
 src/logic/UnaryBooleanStateFormula.h        |   2 +
 src/logic/UnaryPathFormula.cpp              |  38 +---
 src/logic/UnaryPathFormula.h                |  10 -
 src/logic/UnaryStateFormula.cpp             |  42 +---
 src/logic/UnaryStateFormula.h               |  11 +-
 src/logic/UntilFormula.cpp                  |   8 +-
 src/logic/UntilFormula.h                    |   4 +-
 src/modelchecker/AbstractModelChecker.cpp   |  20 +-
 src/modelchecker/AbstractModelChecker.h     |   3 +-
 src/modelchecker/CheckTask.h                |  31 +--
 60 files changed, 874 insertions(+), 681 deletions(-)
 create mode 100644 src/logic/ConditionalFormula.cpp
 create mode 100644 src/logic/ConditionalFormula.h
 delete mode 100644 src/logic/ConditionalPathFormula.cpp
 delete mode 100644 src/logic/ConditionalPathFormula.h
 create mode 100644 src/logic/FormulaVisitor.h
 create mode 100644 src/logic/FormulasForwardDeclarations.h
 create mode 100644 src/logic/FragmentChecker.cpp
 create mode 100644 src/logic/FragmentChecker.h
 create mode 100644 src/logic/FragmentSpecification.cpp
 create mode 100644 src/logic/FragmentSpecification.h

diff --git a/src/builder/DdPrismModelBuilder.cpp b/src/builder/DdPrismModelBuilder.cpp
index 18a156e08..e265f70c5 100644
--- a/src/builder/DdPrismModelBuilder.cpp
+++ b/src/builder/DdPrismModelBuilder.cpp
@@ -227,10 +227,8 @@ namespace storm {
 
             // If we are not required to build all reward models, we determine the reward models we need to build.
             if (!buildAllRewardModels) {
-                if (formula.containsRewardOperator()) {
-                    std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels();
-                    rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
-                }
+                std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels();
+                rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
             }
             
             // Extract all the labels used in the formula.
diff --git a/src/builder/ExplicitPrismModelBuilder.cpp b/src/builder/ExplicitPrismModelBuilder.cpp
index d345d9f05..d7c2f6293 100644
--- a/src/builder/ExplicitPrismModelBuilder.cpp
+++ b/src/builder/ExplicitPrismModelBuilder.cpp
@@ -185,10 +185,8 @@ namespace storm {
             
             // If we are not required to build all reward models, we determine the reward models we need to build.
             if (!buildAllRewardModels) {
-                if (formula.containsRewardOperator()) {
-                    std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels();
-                    rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
-                }
+                std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels();
+                rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
             }
             
             // Extract all the labels used in the formula.
diff --git a/src/logic/AtomicExpressionFormula.cpp b/src/logic/AtomicExpressionFormula.cpp
index 35c7149b0..5f8f0f509 100644
--- a/src/logic/AtomicExpressionFormula.cpp
+++ b/src/logic/AtomicExpressionFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/AtomicExpressionFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         AtomicExpressionFormula::AtomicExpressionFormula(storm::expressions::Expression const& expression) : expression(expression) {
@@ -10,22 +12,10 @@ namespace storm {
             return true;
         }
         
-        bool AtomicExpressionFormula::isPctlStateFormula() const {
-            return true;
+        boost::any AtomicExpressionFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
-        bool AtomicExpressionFormula::isPctlWithConditionalStateFormula() const {
-            return true;
-        }
-                
-        bool AtomicExpressionFormula::isLtlFormula() const {
-            return true;
-        }
-        
-        bool AtomicExpressionFormula::isPropositionalFormula() const {
-            return true;
-        }
-                
         storm::expressions::Expression const& AtomicExpressionFormula::getExpression() const {
             return expression;
         }
diff --git a/src/logic/AtomicExpressionFormula.h b/src/logic/AtomicExpressionFormula.h
index 2b2e36dd5..12636475d 100644
--- a/src/logic/AtomicExpressionFormula.h
+++ b/src/logic/AtomicExpressionFormula.h
@@ -15,10 +15,7 @@ namespace storm {
             
             virtual bool isAtomicExpressionFormula() const override;
             
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool isPropositionalFormula() const override;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             storm::expressions::Expression const& getExpression() const;
             
diff --git a/src/logic/AtomicLabelFormula.cpp b/src/logic/AtomicLabelFormula.cpp
index 36c00eb23..19a5f673f 100644
--- a/src/logic/AtomicLabelFormula.cpp
+++ b/src/logic/AtomicLabelFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/AtomicLabelFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         AtomicLabelFormula::AtomicLabelFormula(std::string const& label) : label(label) {
@@ -10,20 +12,8 @@ namespace storm {
             return true;
         }
         
-        bool AtomicLabelFormula::isPctlStateFormula() const {
-            return true;
-        }
-    
-        bool AtomicLabelFormula::isPctlWithConditionalStateFormula() const {
-            return true;
-        }
-        
-        bool AtomicLabelFormula::isLtlFormula() const {
-            return true;
-        }
-        
-        bool AtomicLabelFormula::isPropositionalFormula() const {
-            return true;
+        boost::any AtomicLabelFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         std::string const& AtomicLabelFormula::getLabel() const {
diff --git a/src/logic/AtomicLabelFormula.h b/src/logic/AtomicLabelFormula.h
index 3d326c211..795704305 100644
--- a/src/logic/AtomicLabelFormula.h
+++ b/src/logic/AtomicLabelFormula.h
@@ -17,10 +17,7 @@ namespace storm {
             
             virtual bool isAtomicLabelFormula() const override;
 
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool isPropositionalFormula() const override;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             std::string const& getLabel() const;
             
diff --git a/src/logic/BinaryBooleanStateFormula.cpp b/src/logic/BinaryBooleanStateFormula.cpp
index 521869129..180ea12c1 100644
--- a/src/logic/BinaryBooleanStateFormula.cpp
+++ b/src/logic/BinaryBooleanStateFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/BinaryBooleanStateFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         BinaryBooleanStateFormula::BinaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryStateFormula(leftSubformula, rightSubformula), operatorType(operatorType) {
@@ -10,8 +12,8 @@ namespace storm {
             return true;
         }
         
-        bool BinaryBooleanStateFormula::isPropositionalFormula() const {
-            return this->getLeftSubformula().isPropositionalFormula() && this->getRightSubformula().isPropositionalFormula();
+        boost::any BinaryBooleanStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         BinaryBooleanStateFormula::OperatorType BinaryBooleanStateFormula::getOperator() const {
diff --git a/src/logic/BinaryBooleanStateFormula.h b/src/logic/BinaryBooleanStateFormula.h
index 23a330ae0..6956e56c6 100644
--- a/src/logic/BinaryBooleanStateFormula.h
+++ b/src/logic/BinaryBooleanStateFormula.h
@@ -19,7 +19,7 @@ namespace storm {
             
             virtual bool isBinaryBooleanStateFormula() const override;
             
-            virtual bool isPropositionalFormula() const override;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             OperatorType getOperator() const;
             
diff --git a/src/logic/BinaryPathFormula.cpp b/src/logic/BinaryPathFormula.cpp
index 5075894c4..4e028d567 100644
--- a/src/logic/BinaryPathFormula.cpp
+++ b/src/logic/BinaryPathFormula.cpp
@@ -9,47 +9,7 @@ namespace storm {
         bool BinaryPathFormula::isBinaryPathFormula() const {
             return true;
         }
-        
-        bool BinaryPathFormula::isPctlPathFormula() const {
-            return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
-        }
-        
-        bool BinaryPathFormula::isPctlWithConditionalPathFormula() const {
-            return this->getLeftSubformula().isPctlWithConditionalPathFormula() && this->getRightSubformula().isPctlWithConditionalPathFormula();
-        }
-        
-        bool BinaryPathFormula::isCslPathFormula() const {
-            return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
-        }
-        
-        bool BinaryPathFormula::isLtlFormula() const {
-            return this->getLeftSubformula().isLtlFormula() && this->getRightSubformula().isLtlFormula();
-        }
-        
-        bool BinaryPathFormula::containsBoundedUntilFormula() const {
-            return this->getLeftSubformula().containsBoundedUntilFormula() || this->getRightSubformula().containsBoundedUntilFormula();
-        }
-        
-        bool BinaryPathFormula::containsNextFormula() const {
-            return this->getLeftSubformula().containsNextFormula() || this->getRightSubformula().containsNextFormula();
-        }
-        
-        bool BinaryPathFormula::containsProbabilityOperator() const {
-            return this->getLeftSubformula().containsProbabilityOperator() || this->getRightSubformula().containsProbabilityOperator();
-        }
-        
-        bool BinaryPathFormula::containsNestedProbabilityOperators() const {
-            return this->getLeftSubformula().containsNestedProbabilityOperators() || this->getRightSubformula().containsNestedProbabilityOperators();
-        }
-        
-        bool BinaryPathFormula::containsRewardOperator() const {
-            return this->getLeftSubformula().containsRewardOperator() || this->getRightSubformula().containsRewardOperator();
-        }
-        
-        bool BinaryPathFormula::containsNestedRewardOperators() const {
-            return this->getLeftSubformula().containsNestedRewardOperators() || this->getRightSubformula().containsNestedRewardOperators();
-        }
-        
+                
         Formula const& BinaryPathFormula::getLeftSubformula() const {
             return *leftSubformula;
         }
diff --git a/src/logic/BinaryPathFormula.h b/src/logic/BinaryPathFormula.h
index 14d162926..fe0526bee 100644
--- a/src/logic/BinaryPathFormula.h
+++ b/src/logic/BinaryPathFormula.h
@@ -17,17 +17,6 @@ namespace storm {
             
             virtual bool isBinaryPathFormula() const override;
             
-            virtual bool isPctlPathFormula() const override;
-            virtual bool isPctlWithConditionalPathFormula() const override;
-            virtual bool isCslPathFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool containsBoundedUntilFormula() const override;
-            virtual bool containsNextFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
-            virtual bool containsRewardOperator() const override;
-            virtual bool containsNestedRewardOperators() const override;
-            
             Formula const& getLeftSubformula() const;
             Formula const& getRightSubformula() const;
             
diff --git a/src/logic/BinaryStateFormula.cpp b/src/logic/BinaryStateFormula.cpp
index bcaa2d39b..9fcdad992 100644
--- a/src/logic/BinaryStateFormula.cpp
+++ b/src/logic/BinaryStateFormula.cpp
@@ -9,47 +9,7 @@ namespace storm {
         bool BinaryStateFormula::isBinaryStateFormula() const {
             return true;
         }
-        
-        bool BinaryStateFormula::isPctlStateFormula() const {
-            return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
-        }
-        
-        bool BinaryStateFormula::isPctlWithConditionalStateFormula() const {
-            return this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula();
-        }
-
-        bool BinaryStateFormula::isCslStateFormula() const {
-            return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
-        }
-        
-        bool BinaryStateFormula::isLtlFormula() const {
-            return this->getLeftSubformula().isLtlFormula() && this->getRightSubformula().isLtlFormula();
-        }
-        
-        bool BinaryStateFormula::containsBoundedUntilFormula() const {
-            return this->getLeftSubformula().containsBoundedUntilFormula() || this->getRightSubformula().containsBoundedUntilFormula();
-        }
-        
-        bool BinaryStateFormula::containsNextFormula() const {
-            return this->getLeftSubformula().containsNextFormula() || this->getRightSubformula().containsNextFormula();
-        }
-        
-        bool BinaryStateFormula::containsProbabilityOperator() const {
-            return this->getLeftSubformula().containsProbabilityOperator() || this->getRightSubformula().containsProbabilityOperator();
-        }
-        
-        bool BinaryStateFormula::containsNestedProbabilityOperators() const {
-            return this->getLeftSubformula().containsNestedProbabilityOperators() || this->getRightSubformula().containsNestedProbabilityOperators();
-        }
-        
-        bool BinaryStateFormula::containsRewardOperator() const {
-            return this->getLeftSubformula().containsRewardOperator() || this->getRightSubformula().containsRewardOperator();
-        }
-        
-        bool BinaryStateFormula::containsNestedRewardOperators() const {
-            return this->containsNestedRewardOperators() || this->getRightSubformula().containsNestedRewardOperators();
-        }
-        
+                
         Formula const& BinaryStateFormula::getLeftSubformula() const {
             return *leftSubformula;
         }
diff --git a/src/logic/BinaryStateFormula.h b/src/logic/BinaryStateFormula.h
index c259aa759..3820097ca 100644
--- a/src/logic/BinaryStateFormula.h
+++ b/src/logic/BinaryStateFormula.h
@@ -15,17 +15,6 @@ namespace storm {
             
             virtual bool isBinaryStateFormula() const override;
 
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool isCslStateFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool containsBoundedUntilFormula() const override;
-            virtual bool containsNextFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
-            virtual bool containsRewardOperator() const override;
-            virtual bool containsNestedRewardOperators() const override;
-            
             Formula const& getLeftSubformula() const;
             Formula const& getRightSubformula() const;
             
diff --git a/src/logic/BooleanLiteralFormula.cpp b/src/logic/BooleanLiteralFormula.cpp
index d021bbc64..897fbf377 100644
--- a/src/logic/BooleanLiteralFormula.cpp
+++ b/src/logic/BooleanLiteralFormula.cpp
@@ -1,11 +1,17 @@
 #include "src/logic/BooleanLiteralFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         BooleanLiteralFormula::BooleanLiteralFormula(bool value) : value(value) {
             // Intenionally left empty.
         }
         
+        bool BooleanLiteralFormula::isBooleanLiteralFormula() const {
+            return true;
+        }
+
         bool BooleanLiteralFormula::isTrueFormula() const {
             return value;
         }
@@ -14,24 +20,8 @@ namespace storm {
             return !value;
         }
         
-        bool BooleanLiteralFormula::isPctlStateFormula() const {
-            return true;
-        }
-        
-        bool BooleanLiteralFormula::isPctlWithConditionalStateFormula() const {
-            return true;
-        }
-        
-        bool BooleanLiteralFormula::isLtlFormula() const {
-            return true;
-        }
-        
-        bool BooleanLiteralFormula::isPropositionalFormula() const {
-            return true;
-        }
-        
-        bool BooleanLiteralFormula::isBooleanLiteralFormula() const {
-            return true;
+        boost::any BooleanLiteralFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         std::shared_ptr<Formula> BooleanLiteralFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
diff --git a/src/logic/BooleanLiteralFormula.h b/src/logic/BooleanLiteralFormula.h
index 1283fde71..405044600 100644
--- a/src/logic/BooleanLiteralFormula.h
+++ b/src/logic/BooleanLiteralFormula.h
@@ -16,11 +16,8 @@ namespace storm {
             virtual bool isBooleanLiteralFormula() const override;
             virtual bool isTrueFormula() const override;
             virtual bool isFalseFormula() const override;
-
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool isPropositionalFormula() const override;
+            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
diff --git a/src/logic/BoundedUntilFormula.cpp b/src/logic/BoundedUntilFormula.cpp
index 9a1f867e1..8f3e73286 100644
--- a/src/logic/BoundedUntilFormula.cpp
+++ b/src/logic/BoundedUntilFormula.cpp
@@ -3,6 +3,8 @@
 #include "src/utility/macros.h"
 #include "src/exceptions/InvalidArgumentException.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         BoundedUntilFormula::BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, double lowerBound, double upperBound) : BinaryPathFormula(leftSubformula, rightSubformula), bounds(std::make_pair(lowerBound, upperBound)) {
@@ -22,30 +24,18 @@ namespace storm {
             return true;
         }
         
-        bool BoundedUntilFormula::containsBoundedUntilFormula() const {
+        bool BoundedUntilFormula::isProbabilityPathFormula() const {
             return true;
         }
         
+        boost::any BoundedUntilFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
+        }
+
         bool BoundedUntilFormula::hasDiscreteTimeBound() const {
             return bounds.which() == 0;
         }
-        
-        bool BoundedUntilFormula::isValidProbabilityPathFormula() const {
-            return true;
-        }
-        
-        bool BoundedUntilFormula::isPctlPathFormula() const {
-            return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
-        }
-        
-        bool BoundedUntilFormula::isPctlWithConditionalPathFormula() const {
-            return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula();
-        }
-        
-        bool BoundedUntilFormula::isCslPathFormula() const {
-            return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
-        }
-        
+                
         std::pair<double, double> const& BoundedUntilFormula::getIntervalBounds() const {
             return boost::get<std::pair<double, double>>(bounds);
         }
diff --git a/src/logic/BoundedUntilFormula.h b/src/logic/BoundedUntilFormula.h
index bc14d8def..222bab142 100644
--- a/src/logic/BoundedUntilFormula.h
+++ b/src/logic/BoundedUntilFormula.h
@@ -15,17 +15,14 @@ namespace storm {
             
             virtual bool isBoundedUntilFormula() const override;
 
-            virtual bool containsBoundedUntilFormula() const override;
+            virtual bool isProbabilityPathFormula() const override;
+            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             bool hasDiscreteTimeBound() const;
             
             std::pair<double, double> const& getIntervalBounds() const;
             uint_fast64_t getDiscreteTimeBound() const;
-            
-            virtual bool isValidProbabilityPathFormula() const override;
-            virtual bool isPctlWithConditionalPathFormula() const override;
-            virtual bool isPctlPathFormula() const override;
-            virtual bool isCslPathFormula() const override;
 
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
diff --git a/src/logic/ConditionalFormula.cpp b/src/logic/ConditionalFormula.cpp
new file mode 100644
index 000000000..2b63fd941
--- /dev/null
+++ b/src/logic/ConditionalFormula.cpp
@@ -0,0 +1,42 @@
+#include "src/logic/ConditionalFormula.h"
+
+#include "src/logic/FormulaVisitor.h"
+
+namespace storm {
+    namespace logic {
+        ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context) : subformula(subformula), conditionFormula(conditionFormula), context(context)  {
+            // Intentionally left empty.
+        }
+        
+        Formula const& ConditionalFormula::getSubformula() const {
+            return *subformula;
+        }
+        
+        Formula const& ConditionalFormula::getConditionFormula() const {
+            return *conditionFormula;
+        }
+        
+        bool ConditionalFormula::isConditionalProbabilityFormula() const {
+            return context == Context::Probability;
+        }
+        
+        bool ConditionalFormula::isConditionalRewardFormula() const {
+            return context == Context::Reward;
+        }
+        
+        boost::any ConditionalFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
+        }
+        
+        std::shared_ptr<Formula> ConditionalFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
+            return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution));
+        }
+        
+        std::ostream& ConditionalFormula::writeToStream(std::ostream& out) const {
+            this->getSubformula().writeToStream(out);
+            out << " || ";
+            this->getConditionFormula().writeToStream(out);
+            return out;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/logic/ConditionalFormula.h b/src/logic/ConditionalFormula.h
new file mode 100644
index 000000000..d7b4dc7cd
--- /dev/null
+++ b/src/logic/ConditionalFormula.h
@@ -0,0 +1,38 @@
+#ifndef STORM_LOGIC_CONDITIONALFORMULA_H_
+#define STORM_LOGIC_CONDITIONALFORMULA_H_
+
+#include "src/logic/BinaryPathFormula.h"
+
+namespace storm {
+    namespace logic {
+        class ConditionalFormula : public Formula {
+        public:
+            enum class Context { Probability, Reward };
+            
+            ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context = Context::Probability);
+            
+            virtual ~ConditionalFormula() {
+                // Intentionally left empty.
+            }
+            
+            Formula const& getSubformula() const;
+            Formula const& getConditionFormula() const;
+
+            virtual bool isConditionalProbabilityFormula() const override;
+            virtual bool isConditionalRewardFormula() const override;
+
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
+
+            virtual std::ostream& writeToStream(std::ostream& out) const override;
+            
+            virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
+            
+        private:
+            std::shared_ptr<Formula const> subformula;
+            std::shared_ptr<Formula const> conditionFormula;
+            Context context;
+        };
+    }
+}
+
+#endif /* STORM_LOGIC_CONDITIONALFORMULA_H_ */
\ No newline at end of file
diff --git a/src/logic/ConditionalPathFormula.cpp b/src/logic/ConditionalPathFormula.cpp
deleted file mode 100644
index 676a83185..000000000
--- a/src/logic/ConditionalPathFormula.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "src/logic/ConditionalPathFormula.h"
-
-namespace storm {
-    namespace logic {
-        ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula) : BinaryPathFormula(leftSubformula, rightSubformula), isRewardFormula(isRewardFormula) {
-            // Intentionally left empty.
-        }
-        
-        bool ConditionalPathFormula::isConditionalPathFormula() const {
-            return true;
-        }
-        
-        bool ConditionalPathFormula::isValidProbabilityPathFormula() const {
-            return true;
-        }
-        
-        bool ConditionalPathFormula::isPctlWithConditionalPathFormula() const {
-            return this->getLeftSubformula().isPctlPathFormula() && this->getRightSubformula().isPctlPathFormula();
-        }
-        
-        bool ConditionalPathFormula::isRewardPathFormula() const {
-            return this->isRewardFormula && this->isValidRewardPathFormula();
-        }
-        
-        bool ConditionalPathFormula::isValidRewardPathFormula() const {
-            return this->getLeftSubformula().isRewardPathFormula() && !this->getLeftSubformula().isConditionalPathFormula() && this->getRightSubformula().isPctlPathFormula();
-        }
-        
-        std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
-            return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
-        }
-        
-        std::ostream& ConditionalPathFormula::writeToStream(std::ostream& out) const {
-            this->getLeftSubformula().writeToStream(out);
-            out << " || ";
-            this->getRightSubformula().writeToStream(out);
-            return out;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/logic/ConditionalPathFormula.h b/src/logic/ConditionalPathFormula.h
deleted file mode 100644
index 94053606b..000000000
--- a/src/logic/ConditionalPathFormula.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef STORM_LOGIC_CONDITIONALPATHFORMULA_H_
-#define STORM_LOGIC_CONDITIONALPATHFORMULA_H_
-
-#include "src/logic/BinaryPathFormula.h"
-
-namespace storm {
-    namespace logic {
-        class ConditionalPathFormula : public BinaryPathFormula {
-        public:
-            ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula = false);
-            
-            virtual ~ConditionalPathFormula() {
-                // Intentionally left empty.
-            }
-            
-            virtual bool isPctlWithConditionalPathFormula() const override;
-            virtual bool isRewardPathFormula() const override;
-            virtual bool isConditionalPathFormula() const override;
-            virtual bool isValidProbabilityPathFormula() const override;
-            virtual bool isValidRewardPathFormula() const override;
-
-            virtual std::ostream& writeToStream(std::ostream& out) const override;
-            
-            virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
-            
-        private:
-            bool isRewardFormula;
-        };
-    }
-}
-
-#endif /* STORM_LOGIC_CONDITIONALPATHFORMULA_H_ */
\ No newline at end of file
diff --git a/src/logic/CumulativeRewardFormula.cpp b/src/logic/CumulativeRewardFormula.cpp
index 2a00c04f3..d8318164d 100644
--- a/src/logic/CumulativeRewardFormula.cpp
+++ b/src/logic/CumulativeRewardFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/CumulativeRewardFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         CumulativeRewardFormula::CumulativeRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) {
@@ -10,16 +12,16 @@ namespace storm {
             // Intentionally left empty.
         }
         
-        bool CumulativeRewardFormula::isRewardPathFormula() const {
+        bool CumulativeRewardFormula::isCumulativeRewardFormula() const {
             return true;
         }
         
-        bool CumulativeRewardFormula::isCumulativeRewardFormula() const {
+        bool CumulativeRewardFormula::isRewardPathFormula() const {
             return true;
         }
         
-        bool CumulativeRewardFormula::isValidRewardPathFormula() const {
-            return true;
+        boost::any CumulativeRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         bool CumulativeRewardFormula::hasDiscreteTimeBound() const {
diff --git a/src/logic/CumulativeRewardFormula.h b/src/logic/CumulativeRewardFormula.h
index 0192a8a49..6a5e8c035 100644
--- a/src/logic/CumulativeRewardFormula.h
+++ b/src/logic/CumulativeRewardFormula.h
@@ -16,10 +16,11 @@ namespace storm {
             virtual ~CumulativeRewardFormula() {
                 // Intentionally left empty.
             }
-            
-            virtual bool isRewardPathFormula() const override;
+
             virtual bool isCumulativeRewardFormula() const override;
-            virtual bool isValidRewardPathFormula() const override;
+            virtual bool isRewardPathFormula() const override;
+            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
 
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp
index 8b09281cd..3d2e6fb57 100644
--- a/src/logic/EventuallyFormula.cpp
+++ b/src/logic/EventuallyFormula.cpp
@@ -1,25 +1,39 @@
 #include "src/logic/EventuallyFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
-        EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula) : UnaryPathFormula(subformula), isRewardFormula(isRewardFormula) {
+        EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context) : UnaryPathFormula(subformula), context(context) {
             // Intentionally left empty.
         }
         
         bool EventuallyFormula::isEventuallyFormula() const {
-            return true;
+            return context == Context::Probability;
+        }
+        
+        bool EventuallyFormula::isReachabilityRewardFormula() const {
+            return context == Context::Reward;
+        }
+        
+        bool EventuallyFormula::isReachbilityExpectedTimeFormula() const {
+            return context == Context::ExpectedTime;
+        }
+        
+        bool EventuallyFormula::isProbabilityPathFormula() const {
+            return this->isEventuallyFormula();
         }
         
         bool EventuallyFormula::isRewardPathFormula() const {
-            return isRewardFormula;
+            return this->isReachabilityRewardFormula();
         }
         
-        bool EventuallyFormula::isValidProbabilityPathFormula() const {
-            return !isRewardFormula;
+        bool EventuallyFormula::isExpectedTimePathFormula() const {
+            return this->isReachbilityExpectedTimeFormula();
         }
         
-        bool EventuallyFormula::isValidRewardPathFormula() const {
-            return isRewardFormula;
+        boost::any EventuallyFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h
index 3b121d320..d7a81fa83 100644
--- a/src/logic/EventuallyFormula.h
+++ b/src/logic/EventuallyFormula.h
@@ -7,23 +7,29 @@ namespace storm {
     namespace logic {
         class EventuallyFormula : public UnaryPathFormula {
         public:
-            EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula = false);
+            enum class Context { Probability, Reward, ExpectedTime };
+            
+            EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context = Context::Probability);
             
             virtual ~EventuallyFormula() {
                 // Intentionally left empty.
             }
             
             virtual bool isEventuallyFormula() const override;
+            virtual bool isReachabilityRewardFormula() const override;
+            virtual bool isReachbilityExpectedTimeFormula() const override;
+            virtual bool isProbabilityPathFormula() const override;
             virtual bool isRewardPathFormula() const override;
-            virtual bool isValidProbabilityPathFormula() const override;
-            virtual bool isValidRewardPathFormula() const override;
+            virtual bool isExpectedTimePathFormula() const override;
+            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
 
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
 
         private:
-            bool isRewardFormula;
+            Context context;
         };
     }
 }
diff --git a/src/logic/ExpectedTimeOperatorFormula.cpp b/src/logic/ExpectedTimeOperatorFormula.cpp
index 8165710a1..5dc8161ae 100644
--- a/src/logic/ExpectedTimeOperatorFormula.cpp
+++ b/src/logic/ExpectedTimeOperatorFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/ExpectedTimeOperatorFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ExpectedTimeOperatorFormula(boost::none, boost::none, subformula) {
@@ -22,20 +24,8 @@ namespace storm {
             return true;
         }
         
-        bool ExpectedTimeOperatorFormula::isPctlStateFormula() const {
-            return this->getSubformula().isPctlStateFormula();
-        }
-        
-        bool ExpectedTimeOperatorFormula::isPctlWithConditionalStateFormula() const {
-            return this->getSubformula().isPctlWithConditionalStateFormula();
-        }
-        
-        bool ExpectedTimeOperatorFormula::containsProbabilityOperator() const {
-            return this->getSubformula().containsProbabilityOperator();
-        }
-        
-        bool ExpectedTimeOperatorFormula::containsNestedProbabilityOperators() const {
-            return this->getSubformula().containsNestedProbabilityOperators();
+        boost::any ExpectedTimeOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) {
diff --git a/src/logic/ExpectedTimeOperatorFormula.h b/src/logic/ExpectedTimeOperatorFormula.h
index 162fb39f8..5e1925b44 100644
--- a/src/logic/ExpectedTimeOperatorFormula.h
+++ b/src/logic/ExpectedTimeOperatorFormula.h
@@ -3,6 +3,8 @@
 
 #include "src/logic/OperatorFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         class ExpectedTimeOperatorFormula : public OperatorFormula {
@@ -18,11 +20,8 @@ namespace storm {
             }
             
             virtual bool isExpectedTimeOperatorFormula() const override;
-            
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
+
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp
index 9f9151b84..6270d5664 100644
--- a/src/logic/Formula.cpp
+++ b/src/logic/Formula.cpp
@@ -71,135 +71,63 @@ namespace storm {
             return false;
         }
         
-        bool Formula::isConditionalPathFormula() const {
+        bool Formula::isConditionalProbabilityFormula() const {
             return false;
         }
         
-        bool Formula::isNextFormula() const {
-            return false;
-        }
-        
-        bool Formula::isLongRunAverageOperatorFormula() const {
-            return false;
-        }
-        
-        bool Formula::isExpectedTimeOperatorFormula() const {
-            return false;
-        }
-        
-        bool Formula::isCumulativeRewardFormula() const {
-            return false;
-        }
-        
-        bool Formula::isInstantaneousRewardFormula() const {
-            return false;
-        }
-        
-        bool Formula::isLongRunAverageRewardFormula() const {
-            return false;
-        }
-        
-        bool Formula::isProbabilityOperatorFormula() const {
-            return false;
-        }
-        
-        bool Formula::isRewardOperatorFormula() const {
-            return false;
-        }
-        
-        bool Formula::isOperatorFormula() const {
+        bool Formula::isConditionalRewardFormula() const {
             return false;
         }
         
-        bool Formula::isPctlFormula() const {
-            return this->isPctlStateFormula() || this->isPctlPathFormula();
-        }
-        
-        bool Formula::isPctlWithConditionalFormula() const {
-            return this->isPctlWithConditionalStateFormula() || this->isPctlWithConditionalPathFormula();
-        }
-        
-        bool Formula::isRewardFormula() const {
-            return this->isRewardStateFormula() || this->isRewardPathFormula();
-        }
-        
-        bool Formula::isCslFormula() const {
-            return this->isCslStateFormula() || this->isCslPathFormula();
-        }
-        
-        bool Formula::isPctlPathFormula() const {
-            return false;
-        }
-        
-        bool Formula::isPctlStateFormula() const {
-            return false;
-        }
-        
-        bool Formula::isPctlWithConditionalPathFormula() const {
-            return false;
-        }
-        
-        bool Formula::isPctlWithConditionalStateFormula() const {
+        bool Formula::isProbabilityPathFormula() const {
             return false;
         }
         
-        bool Formula::isCslPathFormula() const {
-            return this->isPctlPathFormula();
-        }
-        
-        bool Formula::isCslStateFormula() const {
-            return this->isPctlStateFormula();
-        }
-        
         bool Formula::isRewardPathFormula() const {
             return false;
         }
         
-        bool Formula::isRewardStateFormula() const {
+        bool Formula::isExpectedTimePathFormula() const {
             return false;
         }
         
-        bool Formula::isPltlFormula() const {
-            return false;
-        }
-        
-        bool Formula::isLtlFormula() const {
+        bool Formula::isNextFormula() const {
             return false;
         }
         
-        bool Formula::isPropositionalFormula() const {
+        bool Formula::isLongRunAverageOperatorFormula() const {
             return false;
         }
         
-        bool Formula::isValidProbabilityPathFormula() const {
+        bool Formula::isExpectedTimeOperatorFormula() const {
             return false;
         }
         
-        bool Formula::isValidRewardPathFormula() const {
+        bool Formula::isCumulativeRewardFormula() const {
             return false;
         }
         
-        bool Formula::containsBoundedUntilFormula() const {
+        bool Formula::isInstantaneousRewardFormula() const {
             return false;
         }
         
-        bool Formula::containsNextFormula() const {
+        bool Formula::isLongRunAverageRewardFormula() const {
             return false;
         }
         
-        bool Formula::containsProbabilityOperator() const {
+        bool Formula::isReachbilityExpectedTimeFormula() const {
             return false;
         }
         
-        bool Formula::containsNestedProbabilityOperators() const {
+        bool Formula::isProbabilityOperatorFormula() const {
             return false;
         }
         
-        bool Formula::containsRewardOperator() const {
+        bool Formula::isRewardOperatorFormula() const {
             return false;
         }
         
-        bool Formula::containsNestedRewardOperators() const {
+        bool Formula::isOperatorFormula() const {
             return false;
         }
         
@@ -239,12 +167,12 @@ namespace storm {
             return dynamic_cast<UnaryStateFormula const&>(*this);
         }
         
-        ConditionalPathFormula& Formula::asConditionalPathFormula() {
-            return dynamic_cast<ConditionalPathFormula&>(*this);
+        ConditionalFormula& Formula::asConditionalFormula() {
+            return dynamic_cast<ConditionalFormula&>(*this);
         }
         
-        ConditionalPathFormula const& Formula::asConditionalPathFormula() const {
-            return dynamic_cast<ConditionalPathFormula const&>(*this);
+        ConditionalFormula const& Formula::asConditionalFormula() const {
+            return dynamic_cast<ConditionalFormula const&>(*this);
         }
         
         BinaryBooleanStateFormula& Formula::asBinaryBooleanStateFormula() {
diff --git a/src/logic/Formula.h b/src/logic/Formula.h
index cf4333eb4..ae879fce6 100644
--- a/src/logic/Formula.h
+++ b/src/logic/Formula.h
@@ -6,37 +6,18 @@
 #include <iostream>
 #include <set>
 
+#include <boost/any.hpp>
+
 #include "src/storage/expressions/Variable.h"
 #include "src/storage/expressions/Expression.h"
 
+#include "src/logic/FormulasForwardDeclarations.h"
+
 namespace storm {
     namespace logic {
-        // Forward-declare all formula classes.
-        class PathFormula;
-        class StateFormula;
-        class BinaryStateFormula;
-        class UnaryStateFormula;
-        class BinaryBooleanStateFormula;
-        class UnaryBooleanStateFormula;
-        class BooleanLiteralFormula;
-        class AtomicExpressionFormula;
-        class AtomicLabelFormula;
-        class UntilFormula;
-        class BoundedUntilFormula;
-        class EventuallyFormula;
-        class GloballyFormula;
-        class BinaryPathFormula;
-        class UnaryPathFormula;
-        class ConditionalPathFormula;
-        class NextFormula;
-        class LongRunAverageOperatorFormula;
-        class ExpectedTimeOperatorFormula;
-        class CumulativeRewardFormula;
-        class InstantaneousRewardFormula;
-        class LongRunAverageRewardFormula;
-        class ProbabilityOperatorFormula;
-        class RewardOperatorFormula;
-        class OperatorFormula;
+
+        // Forward-declare visitor for accept() method.
+        class FormulaVisitor;
 
         // Also foward-declare base model checker class.
         class ModelChecker;
@@ -49,59 +30,57 @@ namespace storm {
             };
             
             friend std::ostream& operator<<(std::ostream& out, Formula const& formula);
-            
-            // Methods for querying the exact formula type.
+
+            // Basic formula types.
             virtual bool isPathFormula() const;
             virtual bool isStateFormula() const;
-            virtual bool isBinaryStateFormula() const;
-            virtual bool isUnaryStateFormula() const;
+            virtual bool isConditionalProbabilityFormula() const;
+            virtual bool isConditionalRewardFormula() const;
+            
+            virtual bool isProbabilityPathFormula() const;
+            virtual bool isRewardPathFormula() const;
+            virtual bool isExpectedTimePathFormula() const;
+
             virtual bool isBinaryBooleanStateFormula() const;
             virtual bool isUnaryBooleanStateFormula() const;
+
+            // Operator formulas.
+            virtual bool isOperatorFormula() const;
+            virtual bool isLongRunAverageOperatorFormula() const;
+            virtual bool isExpectedTimeOperatorFormula() const;
+            virtual bool isProbabilityOperatorFormula() const;
+            virtual bool isRewardOperatorFormula() const;
+
+            // Atomic state formulas.
             virtual bool isBooleanLiteralFormula() const;
             virtual bool isTrueFormula() const;
             virtual bool isFalseFormula() const;
             virtual bool isAtomicExpressionFormula() const;
             virtual bool isAtomicLabelFormula() const;
+
+            // Probability path formulas.
+            virtual bool isNextFormula() const;
             virtual bool isUntilFormula() const;
             virtual bool isBoundedUntilFormula() const;
             virtual bool isEventuallyFormula() const;
             virtual bool isGloballyFormula() const;
-            virtual bool isBinaryPathFormula() const;
-            virtual bool isUnaryPathFormula() const;
-            virtual bool isConditionalPathFormula() const;
-            virtual bool isNextFormula() const;
-            virtual bool isLongRunAverageOperatorFormula() const;
-            virtual bool isExpectedTimeOperatorFormula() const;
+
+            // Reward formulas.
             virtual bool isCumulativeRewardFormula() const;
             virtual bool isInstantaneousRewardFormula() const;
+            virtual bool isReachabilityRewardFormula() const;
             virtual bool isLongRunAverageRewardFormula() const;
-            virtual bool isProbabilityOperatorFormula() const;
-            virtual bool isRewardOperatorFormula() const;
-            virtual bool isOperatorFormula() const;
+            
+            // Expected time formulas.
+            virtual bool isReachbilityExpectedTimeFormula() const;
+            
+            // Type checks for abstract intermediate classes.
+            virtual bool isBinaryPathFormula() const;
+            virtual bool isBinaryStateFormula() const;
+            virtual bool isUnaryPathFormula() const;
+            virtual bool isUnaryStateFormula() const;
 
-            bool isPctlFormula() const;
-            bool isPctlWithConditionalFormula() const;
-            bool isRewardFormula() const;
-            bool isCslFormula() const;
-            virtual bool isPctlPathFormula() const;
-            virtual bool isPctlStateFormula() const;
-            virtual bool isPctlWithConditionalPathFormula() const;
-            virtual bool isPctlWithConditionalStateFormula() const;
-            virtual bool isCslPathFormula() const;
-            virtual bool isCslStateFormula() const;
-            virtual bool isRewardPathFormula() const;
-            virtual bool isRewardStateFormula() const;
-            virtual bool isPltlFormula() const;
-            virtual bool isLtlFormula() const;
-            virtual bool isPropositionalFormula() const;
-            virtual bool isValidProbabilityPathFormula() const;
-            virtual bool isValidRewardPathFormula() const;
-            virtual bool containsBoundedUntilFormula() const;
-            virtual bool containsNextFormula() const;
-            virtual bool containsProbabilityOperator() const;
-            virtual bool containsNestedProbabilityOperators() const;
-            virtual bool containsRewardOperator() const;
-            virtual bool containsNestedRewardOperators() const;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const = 0;
             
             static std::shared_ptr<Formula const> getTrueFormula();
             
@@ -150,8 +129,8 @@ namespace storm {
             UnaryPathFormula& asUnaryPathFormula();
             UnaryPathFormula const& asUnaryPathFormula() const;
             
-            ConditionalPathFormula& asConditionalPathFormula();
-            ConditionalPathFormula const& asConditionalPathFormula() const;
+            ConditionalFormula& asConditionalFormula();
+            ConditionalFormula const& asConditionalFormula() const;
             
             NextFormula& asNextFormula();
             NextFormula const& asNextFormula() const;
diff --git a/src/logic/FormulaVisitor.h b/src/logic/FormulaVisitor.h
new file mode 100644
index 000000000..a2e5b1a4f
--- /dev/null
+++ b/src/logic/FormulaVisitor.h
@@ -0,0 +1,36 @@
+#ifndef STORM_LOGIC_FORMULAVISITOR_H_
+#define STORM_LOGIC_FORMULAVISITOR_H_
+
+#include <boost/any.hpp>
+
+#include "src/logic/FormulasForwardDeclarations.h"
+
+namespace storm {
+    namespace logic {
+
+        class FormulaVisitor {
+        public:
+            virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(NextFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const = 0;
+            virtual boost::any visit(UntilFormula const& f, boost::any const& data) const = 0;
+        };
+        
+    }
+}
+
+#endif /* STORM_LOGIC_FORMULAVISITOR_H_ */
\ No newline at end of file
diff --git a/src/logic/Formulas.h b/src/logic/Formulas.h
index 7da9321c6..a5218eeb8 100644
--- a/src/logic/Formulas.h
+++ b/src/logic/Formulas.h
@@ -23,7 +23,7 @@
 #include "src/logic/UnaryPathFormula.h"
 #include "src/logic/UnaryStateFormula.h"
 #include "src/logic/UntilFormula.h"
-#include "src/logic/ConditionalPathFormula.h"
+#include "src/logic/ConditionalFormula.h"
 #include "src/logic/ProbabilityOperatorFormula.h"
 #include "src/logic/RewardOperatorFormula.h"
 #include "src/logic/ComparisonType.h"
\ No newline at end of file
diff --git a/src/logic/FormulasForwardDeclarations.h b/src/logic/FormulasForwardDeclarations.h
new file mode 100644
index 000000000..13b4c326c
--- /dev/null
+++ b/src/logic/FormulasForwardDeclarations.h
@@ -0,0 +1,36 @@
+#ifndef STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_
+#define STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_
+
+namespace storm {
+    namespace logic {
+        // Forward-declare all formula classes.
+        class Formula;
+        class AtomicExpressionFormula;
+        class AtomicLabelFormula;
+        class BinaryBooleanStateFormula;
+        class BinaryPathFormula;
+        class BinaryStateFormula;
+        class BooleanLiteralFormula;
+        class BoundedUntilFormula;
+        class ConditionalFormula;
+        class CumulativeRewardFormula;
+        class EventuallyFormula;
+        class ExpectedTimeOperatorFormula;
+        class GloballyFormula;
+        class InstantaneousRewardFormula;
+        class LongRunAverageOperatorFormula;
+        class LongRunAverageRewardFormula;
+        class NextFormula;
+        class OperatorFormula;
+        class PathFormula;
+        class ProbabilityOperatorFormula;
+        class RewardOperatorFormula;
+        class StateFormula;
+        class UnaryBooleanStateFormula;
+        class UnaryPathFormula;
+        class UnaryStateFormula;
+        class UntilFormula;
+    }
+}
+
+#endif /* STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_ */
\ No newline at end of file
diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp
new file mode 100644
index 000000000..d94056f58
--- /dev/null
+++ b/src/logic/FragmentChecker.cpp
@@ -0,0 +1,118 @@
+#include "src/logic/FragmentChecker.h"
+
+#include "src/logic/Formulas.h"
+
+namespace storm {
+    namespace logic {
+        bool FragmentChecker::conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const {
+            boost::any result = f.accept(*this, specification);
+            return boost::any_cast<bool>(result);
+        }
+        
+        boost::any FragmentChecker::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areAtomicExpressionFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(AtomicLabelFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areAtomicLabelFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            bool result = specification.areBinaryBooleanStateFormulasAllowed();
+            result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, specification));
+            result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, specification));
+            return result;
+        }
+        
+        boost::any FragmentChecker::visit(BooleanLiteralFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areBooleanLiteralFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(BoundedUntilFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            bool result = specification.areBoundedUntilFormulasAllowed();
+            result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
+            result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
+            return result;
+        }
+        
+        boost::any FragmentChecker::visit(ConditionalFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            bool result = true;
+            if (f.isConditionalProbabilityFormula()) {
+                result &= specification.areConditionalProbabilityFormulasAllowed();
+            } else if (f.Formula::isConditionalRewardFormula()) {
+                result &= specification.areConditionalRewardFormulasFormulasAllowed();
+            }
+            result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data));
+            return result;
+        }
+        
+        boost::any FragmentChecker::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areCumulativeRewardFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(EventuallyFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            bool result = specification.areEventuallyFormulasAllowed();
+            result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            return result;
+        }
+        
+        boost::any FragmentChecker::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areExpectedTimeOperatorsAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(GloballyFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areGloballyFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areInstantaneousRewardFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areLongRunAverageOperatorsAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areLongRunAverageRewardFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(NextFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areNextFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areProbabilityOperatorsAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areRewardOperatorsAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areUnaryBooleanStateFormulasAllowed();
+        }
+        
+        boost::any FragmentChecker::visit(UntilFormula const& f, boost::any const& data) const {
+            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            return specification.areUntilFormulasAllowed();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/logic/FragmentChecker.h b/src/logic/FragmentChecker.h
new file mode 100644
index 000000000..3d22390e6
--- /dev/null
+++ b/src/logic/FragmentChecker.h
@@ -0,0 +1,39 @@
+#ifndef STORM_LOGIC_FRAGMENTCHECKER_H_
+#define STORM_LOGIC_FRAGMENTCHECKER_H_
+
+#include "src/logic/FormulaVisitor.h"
+
+#include "src/logic/FragmentSpecification.h"
+
+namespace storm {
+    namespace logic {
+        
+        class FragmentChecker : public FormulaVisitor {
+        public:
+            bool conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const;
+            
+            virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(NextFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override;
+        };
+        
+    }
+}
+
+
+#endif /* STORM_LOGIC_FRAGMENTCHECKER_H_ */
\ No newline at end of file
diff --git a/src/logic/FragmentSpecification.cpp b/src/logic/FragmentSpecification.cpp
new file mode 100644
index 000000000..eeb697582
--- /dev/null
+++ b/src/logic/FragmentSpecification.cpp
@@ -0,0 +1,209 @@
+#include "src/logic/FragmentSpecification.h"
+
+namespace storm {
+    namespace logic {
+        
+        FragmentSpecification FragmentSpecification::copy() const {
+            return FragmentSpecification(*this);
+        }
+        
+        bool FragmentSpecification::areProbabilityOperatorsAllowed() const {
+            return probabilityOperator;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setProbabilityOperatorsAllowed(bool newValue) {
+            this->probabilityOperator = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areRewardOperatorsAllowed() const {
+            return rewardOperator;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setRewardOperatorsAllowed(bool newValue) {
+            this->rewardOperator = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areExpectedTimeOperatorsAllowed() const {
+            return expectedTimeOperator;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setExpectedTimeOperatorsAllowed(bool newValue) {
+            this->expectedTimeOperator = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areLongRunAverageOperatorsAllowed() const {
+            return longRunAverageOperator;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setLongRunAverageOperatorsAllowed(bool newValue) {
+            this->longRunAverageOperator = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areGloballyFormulasAllowed() const {
+            return globallyFormula;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setGloballyFormulasAllowed(bool newValue) {
+            this->globallyFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areEventuallyFormulasAllowed() const {
+            return eventuallyFormula;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setEventuallyFormulasAllowed(bool newValue) {
+            this->eventuallyFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areNextFormulasAllowed() const {
+            return nextFormula;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setNextFormulasAllowed(bool newValue) {
+            this->nextFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areUntilFormulasAllowed() const {
+            return untilFormula;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setUntilFormulasAllowed(bool newValue) {
+            this->untilFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areBoundedUntilFormulasAllowed() const {
+            return boundedUntilFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setBoundedUntilFormulasAllowed(bool newValue) {
+            this->boundedUntilFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areAtomicExpressionFormulasAllowed() const {
+            return atomicExpressionFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setAtomicExpressionFormulasAllowed(bool newValue) {
+            this->atomicExpressionFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areAtomicLabelFormulasAllowed() const {
+            return atomicLabelFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setAtomicLabelFormulasAllowed(bool newValue) {
+            this->atomicLabelFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areBooleanLiteralFormulasAllowed() const {
+            return booleanLiteralFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setBooleanLiteralFormulasAllowed(bool newValue) {
+            this->booleanLiteralFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areUnaryBooleanStateFormulasAllowed() const {
+            return unaryBooleanStateFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setUnaryBooleanStateFormulasAllowed(bool newValue) {
+            this->unaryBooleanStateFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areBinaryBooleanStateFormulasAllowed() const {
+            return binaryBooleanStateFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setBinaryBooleanStateFormulasAllowed(bool newValue) {
+            this->binaryBooleanStateFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areCumulativeRewardFormulasAllowed() const {
+            return cumulativeRewardFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setCumulativeRewardFormulasAllowed(bool newValue) {
+            this->cumulativeRewardFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areInstantaneousRewardFormulasAllowed() const {
+            return instantaneousRewardFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setInstantaneousFormulasAllowed(bool newValue) {
+            this->instantaneousRewardFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areReachabilityRewardFormulasAllowed() const {
+            return reachabilityRewardFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setReachabilityRewardFormulasAllowed(bool newValue) {
+            this->reachabilityRewardFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areLongRunAverageRewardFormulasAllowed() const {
+            return longRunAverageRewardFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setLongRunAverageRewardFormulasAllowed(bool newValue) {
+            this->longRunAverageRewardFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areConditionalProbabilityFormulasAllowed() const {
+            return conditionalProbabilityFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setConditionalProbabilityFormulasAllowed(bool newValue) {
+            this->conditionalProbabilityFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areConditionalRewardFormulasFormulasAllowed() const {
+            return conditionalRewardFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setConditionalRewardFormulasAllowed(bool newValue) {
+            this->conditionalRewardFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areReachbilityExpectedTimeFormulasAllowed() const {
+            return reachabilityExpectedTimeFormula;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setReachbilityExpectedTimeFormulasAllowed(bool newValue) {
+            this->reachabilityExpectedTimeFormula = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areNestedOperatorsAllowed() const {
+            return this->nestedOperators;
+        }
+            
+        FragmentSpecification& FragmentSpecification::setNestedOperatorsAllowed(bool newValue) {
+            this->nestedOperators = newValue;
+            return *this;
+        }
+        
+    }
+}
\ No newline at end of file
diff --git a/src/logic/FragmentSpecification.h b/src/logic/FragmentSpecification.h
new file mode 100644
index 000000000..91099703f
--- /dev/null
+++ b/src/logic/FragmentSpecification.h
@@ -0,0 +1,112 @@
+#ifndef STORM_LOGIC_FRAGMENTSPECIFICATION_H_
+#define STORM_LOGIC_FRAGMENTSPECIFICATION_H_
+
+namespace storm {
+    namespace logic {
+        class FragmentSpecification {
+        public:
+            FragmentSpecification copy() const;
+            
+            bool areProbabilityOperatorsAllowed() const;
+            FragmentSpecification& setProbabilityOperatorsAllowed(bool newValue);
+            
+            bool areRewardOperatorsAllowed() const;
+            FragmentSpecification& setRewardOperatorsAllowed(bool newValue);
+            
+            bool areExpectedTimeOperatorsAllowed() const;
+            FragmentSpecification& setExpectedTimeOperatorsAllowed(bool newValue);
+
+            bool areLongRunAverageOperatorsAllowed() const;
+            FragmentSpecification& setLongRunAverageOperatorsAllowed(bool newValue);
+
+            bool areGloballyFormulasAllowed() const;
+            FragmentSpecification& setGloballyFormulasAllowed(bool newValue);
+
+            bool areEventuallyFormulasAllowed() const;
+            FragmentSpecification& setEventuallyFormulasAllowed(bool newValue);
+
+            bool areNextFormulasAllowed() const;
+            FragmentSpecification& setNextFormulasAllowed(bool newValue);
+
+            bool areUntilFormulasAllowed() const;
+            FragmentSpecification& setUntilFormulasAllowed(bool newValue);
+
+            bool areBoundedUntilFormulasAllowed() const;
+            FragmentSpecification& setBoundedUntilFormulasAllowed(bool newValue);
+
+            bool areAtomicExpressionFormulasAllowed() const;
+            FragmentSpecification& setAtomicExpressionFormulasAllowed(bool newValue);
+
+            bool areAtomicLabelFormulasAllowed() const;
+            FragmentSpecification& setAtomicLabelFormulasAllowed(bool newValue);
+
+            bool areBooleanLiteralFormulasAllowed() const;
+            FragmentSpecification& setBooleanLiteralFormulasAllowed(bool newValue);
+
+            bool areUnaryBooleanStateFormulasAllowed() const;
+            FragmentSpecification& setUnaryBooleanStateFormulasAllowed(bool newValue);
+
+            bool areBinaryBooleanStateFormulasAllowed() const;
+            FragmentSpecification& setBinaryBooleanStateFormulasAllowed(bool newValue);
+
+            bool areCumulativeRewardFormulasAllowed() const;
+            FragmentSpecification& setCumulativeRewardFormulasAllowed(bool newValue);
+
+            bool areInstantaneousRewardFormulasAllowed() const;
+            FragmentSpecification& setInstantaneousFormulasAllowed(bool newValue);
+
+            bool areReachabilityRewardFormulasAllowed() const;
+            FragmentSpecification& setReachabilityRewardFormulasAllowed(bool newValue);
+            
+            bool areLongRunAverageRewardFormulasAllowed() const;
+            FragmentSpecification& setLongRunAverageRewardFormulasAllowed(bool newValue);
+
+            bool areConditionalProbabilityFormulasAllowed() const;
+            FragmentSpecification& setConditionalProbabilityFormulasAllowed(bool newValue);
+
+            bool areConditionalRewardFormulasFormulasAllowed() const;
+            FragmentSpecification& setConditionalRewardFormulasAllowed(bool newValue);
+
+            bool areReachbilityExpectedTimeFormulasAllowed() const;
+            FragmentSpecification& setReachbilityExpectedTimeFormulasAllowed(bool newValue);
+
+            bool areNestedOperatorsAllowed() const;
+            FragmentSpecification& setNestedOperatorsAllowed(bool newValue);
+
+        private:
+            // Flags that indicate whether it is legal to see such a formula.
+            bool probabilityOperator;
+            bool rewardOperator;
+            bool expectedTimeOperator;
+            bool longRunAverageOperator;
+            
+            bool globallyFormula;
+            bool eventuallyFormula;
+            bool nextFormula;
+            bool untilFormula;
+            bool boundedUntilFormula;
+            
+            bool atomicExpressionFormula;
+            bool atomicLabelFormula;
+            bool booleanLiteralFormula;
+            bool unaryBooleanStateFormula;
+            bool binaryBooleanStateFormula;
+            
+            bool cumulativeRewardFormula;
+            bool instantaneousRewardFormula;
+            bool reachabilityRewardFormula;
+            bool longRunAverageRewardFormula;
+            
+            bool conditionalProbabilityFormula;
+            bool conditionalRewardFormula;
+            
+            bool reachabilityExpectedTimeFormula;
+            
+            // Members that indicate certain restrictions.
+            bool nestedOperators;
+            
+        };
+    }
+}
+
+#endif /* STORM_LOGIC_FRAGMENTSPECIFICATION_H_ */
\ No newline at end of file
diff --git a/src/logic/GloballyFormula.cpp b/src/logic/GloballyFormula.cpp
index 5ddfd8feb..df33f0b52 100644
--- a/src/logic/GloballyFormula.cpp
+++ b/src/logic/GloballyFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/GloballyFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         GloballyFormula::GloballyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) {
@@ -10,9 +12,13 @@ namespace storm {
             return true;
         }
 
-        bool GloballyFormula::isValidProbabilityPathFormula() const {
+        bool GloballyFormula::isProbabilityPathFormula() const {
             return true;
         }
+        
+        boost::any GloballyFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
+        }
 
         std::shared_ptr<Formula> GloballyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<GloballyFormula>(this->getSubformula().substitute(substitution));
diff --git a/src/logic/GloballyFormula.h b/src/logic/GloballyFormula.h
index e3fc82f2d..011c61de9 100644
--- a/src/logic/GloballyFormula.h
+++ b/src/logic/GloballyFormula.h
@@ -14,7 +14,9 @@ namespace storm {
             }
             
             virtual bool isGloballyFormula() const override;
-            virtual bool isValidProbabilityPathFormula() const override;
+            virtual bool isProbabilityPathFormula() const override;
+
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
 
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
diff --git a/src/logic/InstantaneousRewardFormula.cpp b/src/logic/InstantaneousRewardFormula.cpp
index 7289f18e9..4f1f65429 100644
--- a/src/logic/InstantaneousRewardFormula.cpp
+++ b/src/logic/InstantaneousRewardFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/InstantaneousRewardFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         InstantaneousRewardFormula::InstantaneousRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) {
@@ -14,12 +16,12 @@ namespace storm {
             return true;
         }
         
-        bool InstantaneousRewardFormula::isValidRewardPathFormula() const {
+        bool InstantaneousRewardFormula::isRewardPathFormula() const {
             return true;
         }
         
-        bool InstantaneousRewardFormula::isRewardPathFormula() const {
-            return true;
+        boost::any InstantaneousRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         bool InstantaneousRewardFormula::hasDiscreteTimeBound() const {
diff --git a/src/logic/InstantaneousRewardFormula.h b/src/logic/InstantaneousRewardFormula.h
index 967f03a2b..069bf21bd 100644
--- a/src/logic/InstantaneousRewardFormula.h
+++ b/src/logic/InstantaneousRewardFormula.h
@@ -17,10 +17,12 @@ namespace storm {
                 // Intentionally left empty.
             }
             
-            virtual bool isRewardPathFormula() const override;
             virtual bool isInstantaneousRewardFormula() const override;
-            virtual bool isValidRewardPathFormula() const override;
 
+            virtual bool isRewardPathFormula() const override;
+            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
+            
             virtual std::ostream& writeToStream(std::ostream& out) const override;
             
             bool hasDiscreteTimeBound() const;
diff --git a/src/logic/LongRunAverageOperatorFormula.cpp b/src/logic/LongRunAverageOperatorFormula.cpp
index 1563dc67e..c9d781905 100644
--- a/src/logic/LongRunAverageOperatorFormula.cpp
+++ b/src/logic/LongRunAverageOperatorFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/LongRunAverageOperatorFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(std::shared_ptr<Formula const> const& subformula) : LongRunAverageOperatorFormula(boost::none, boost::none, subformula) {
@@ -22,20 +24,8 @@ namespace storm {
             return true;
         }
         
-        bool LongRunAverageOperatorFormula::isPctlStateFormula() const {
-            return this->getSubformula().isPctlStateFormula();
-        }
-        
-        bool LongRunAverageOperatorFormula::isPctlWithConditionalStateFormula() const {
-            return this->getSubformula().isPctlWithConditionalStateFormula();
-        }
-        
-        bool LongRunAverageOperatorFormula::containsProbabilityOperator() const {
-            return this->getSubformula().containsProbabilityOperator();
-        }
-        
-        bool LongRunAverageOperatorFormula::containsNestedProbabilityOperators() const {
-            return this->getSubformula().containsNestedProbabilityOperators();
+        boost::any LongRunAverageOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) {
diff --git a/src/logic/LongRunAverageOperatorFormula.h b/src/logic/LongRunAverageOperatorFormula.h
index 85eb9f969..d4a785b80 100644
--- a/src/logic/LongRunAverageOperatorFormula.h
+++ b/src/logic/LongRunAverageOperatorFormula.h
@@ -19,10 +19,7 @@ namespace storm {
             
             virtual bool isLongRunAverageOperatorFormula() const override;
             
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
 
diff --git a/src/logic/LongRunAverageRewardFormula.cpp b/src/logic/LongRunAverageRewardFormula.cpp
index 9d9dc898d..30bfd7ba9 100644
--- a/src/logic/LongRunAverageRewardFormula.cpp
+++ b/src/logic/LongRunAverageRewardFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/LongRunAverageRewardFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         LongRunAverageRewardFormula::LongRunAverageRewardFormula() {
@@ -10,12 +12,12 @@ namespace storm {
             return true;
         }
         
-        bool LongRunAverageRewardFormula::isValidRewardPathFormula() const {
+        bool LongRunAverageRewardFormula::isRewardPathFormula() const {
             return true;
         }
         
-        bool LongRunAverageRewardFormula::isRewardPathFormula() const {
-            return true;
+        boost::any LongRunAverageRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
diff --git a/src/logic/LongRunAverageRewardFormula.h b/src/logic/LongRunAverageRewardFormula.h
index 929a6f3c8..3dfea465e 100644
--- a/src/logic/LongRunAverageRewardFormula.h
+++ b/src/logic/LongRunAverageRewardFormula.h
@@ -13,9 +13,10 @@ namespace storm {
                 // Intentionally left empty.
             }
             
-            virtual bool isRewardPathFormula() const override;
             virtual bool isLongRunAverageRewardFormula() const override;
-            virtual bool isValidRewardPathFormula() const override;
+            virtual bool isRewardPathFormula() const override;
+
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
 
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
diff --git a/src/logic/NextFormula.cpp b/src/logic/NextFormula.cpp
index b7400eb7d..e73171a95 100644
--- a/src/logic/NextFormula.cpp
+++ b/src/logic/NextFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/NextFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         NextFormula::NextFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) {
@@ -10,12 +12,12 @@ namespace storm {
             return true;
         }
         
-        bool NextFormula::isValidProbabilityPathFormula() const {
+        bool NextFormula::isProbabilityPathFormula() const {
             return true;
         }
         
-        bool NextFormula::containsNextFormula() const {
-            return true;
+        boost::any NextFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         std::shared_ptr<Formula> NextFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
diff --git a/src/logic/NextFormula.h b/src/logic/NextFormula.h
index f0de43cc6..bade60456 100644
--- a/src/logic/NextFormula.h
+++ b/src/logic/NextFormula.h
@@ -14,9 +14,9 @@ namespace storm {
             }
             
             virtual bool isNextFormula() const override;
-            virtual bool isValidProbabilityPathFormula() const override;
+            virtual bool isProbabilityPathFormula() const override;
 
-            virtual bool containsNextFormula() const override;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
diff --git a/src/logic/ProbabilityOperatorFormula.cpp b/src/logic/ProbabilityOperatorFormula.cpp
index cb584b034..09680cbc5 100644
--- a/src/logic/ProbabilityOperatorFormula.cpp
+++ b/src/logic/ProbabilityOperatorFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/ProbabilityOperatorFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         ProbabilityOperatorFormula::ProbabilityOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ProbabilityOperatorFormula(boost::none, boost::none, subformula) {
@@ -22,30 +24,10 @@ namespace storm {
             return true;
         }
         
-        bool ProbabilityOperatorFormula::isPctlStateFormula() const {
-            return this->getSubformula().isPctlPathFormula();
-        }
-        
-        bool ProbabilityOperatorFormula::isPctlWithConditionalStateFormula() const {
-            return this->getSubformula().isPctlWithConditionalPathFormula();
-        }
-        
-        bool ProbabilityOperatorFormula::isCslStateFormula() const {
-            return this->getSubformula().isCslPathFormula();
-        }
-        
-        bool ProbabilityOperatorFormula::isPltlFormula() const {
-            return this->getSubformula().isLtlFormula();
+        boost::any ProbabilityOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
-        
-        bool ProbabilityOperatorFormula::containsProbabilityOperator() const {
-            return true;
-        }
-        
-        bool ProbabilityOperatorFormula::containsNestedProbabilityOperators() const {
-            return this->getSubformula().containsProbabilityOperator();
-        }
-        
+                
         ProbabilityOperatorFormula::ProbabilityOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) {
             // Intentionally left empty.
         }
diff --git a/src/logic/ProbabilityOperatorFormula.h b/src/logic/ProbabilityOperatorFormula.h
index 163e05f58..1172247d0 100644
--- a/src/logic/ProbabilityOperatorFormula.h
+++ b/src/logic/ProbabilityOperatorFormula.h
@@ -17,14 +17,9 @@ namespace storm {
                 // Intentionally left empty.
             }
             
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool isCslStateFormula() const override;
-            virtual bool isPltlFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
-            
             virtual bool isProbabilityOperatorFormula() const override;
+
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp
index 0eea0eedc..0e025c208 100644
--- a/src/logic/RewardOperatorFormula.cpp
+++ b/src/logic/RewardOperatorFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/RewardOperatorFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::none, boost::none, subformula) {
@@ -22,20 +24,8 @@ namespace storm {
             return true;
         }
         
-        bool RewardOperatorFormula::isRewardStateFormula() const {
-            return this->getSubformula().isRewardPathFormula();
-        }
-        
-        bool RewardOperatorFormula::containsRewardOperator() const {
-            return true;
-        }
-        
-        bool RewardOperatorFormula::containsNestedRewardOperators() const {
-            return this->getSubformula().containsRewardOperator();
-        }
-        
-        bool RewardOperatorFormula::hasRewardModelName() const {
-            return static_cast<bool>(this->rewardModelName);
+        boost::any RewardOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         std::string const& RewardOperatorFormula::getRewardModelName() const {
diff --git a/src/logic/RewardOperatorFormula.h b/src/logic/RewardOperatorFormula.h
index 0cbfe955e..6bcf015d8 100644
--- a/src/logic/RewardOperatorFormula.h
+++ b/src/logic/RewardOperatorFormula.h
@@ -19,11 +19,9 @@ namespace storm {
             }
             
             virtual bool isRewardOperatorFormula() const override;
-            virtual bool isRewardStateFormula() const override;
 
-            virtual bool containsRewardOperator() const override;
-            virtual bool containsNestedRewardOperators() const override;
-            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
+
             virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override;
             
             virtual std::ostream& writeToStream(std::ostream& out) const override;
diff --git a/src/logic/UnaryBooleanStateFormula.cpp b/src/logic/UnaryBooleanStateFormula.cpp
index ec9a4ff0a..6d4f9ecdd 100644
--- a/src/logic/UnaryBooleanStateFormula.cpp
+++ b/src/logic/UnaryBooleanStateFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/UnaryBooleanStateFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         UnaryBooleanStateFormula::UnaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& subformula) : UnaryStateFormula(subformula), operatorType(operatorType) {
@@ -9,6 +11,10 @@ namespace storm {
         bool UnaryBooleanStateFormula::isUnaryBooleanStateFormula() const {
             return true;
         }
+
+        boost::any UnaryBooleanStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
+        }
         
         UnaryBooleanStateFormula::OperatorType UnaryBooleanStateFormula::getOperator() const {
             return operatorType;
diff --git a/src/logic/UnaryBooleanStateFormula.h b/src/logic/UnaryBooleanStateFormula.h
index fa0a83023..93d45f862 100644
--- a/src/logic/UnaryBooleanStateFormula.h
+++ b/src/logic/UnaryBooleanStateFormula.h
@@ -17,6 +17,8 @@ namespace storm {
             
             virtual bool isUnaryBooleanStateFormula() const override;
 
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
+            
             OperatorType getOperator() const;
             
             virtual bool isNot() const;
diff --git a/src/logic/UnaryPathFormula.cpp b/src/logic/UnaryPathFormula.cpp
index 01ccadde8..3e0cdaebc 100644
--- a/src/logic/UnaryPathFormula.cpp
+++ b/src/logic/UnaryPathFormula.cpp
@@ -9,43 +9,7 @@ namespace storm {
         bool UnaryPathFormula::isUnaryPathFormula() const {
             return true;
         }
-        
-        bool UnaryPathFormula::isPctlPathFormula() const {
-            return this->getSubformula().isPctlStateFormula();
-        }
-        
-        bool UnaryPathFormula::isPctlWithConditionalPathFormula() const {
-            return this->getSubformula().isPctlWithConditionalStateFormula();
-        }
-        
-        bool UnaryPathFormula::isLtlFormula() const {
-            return this->getSubformula().isLtlFormula();
-        }
-        
-        bool UnaryPathFormula::containsBoundedUntilFormula() const {
-            return this->getSubformula().containsBoundedUntilFormula();
-        }
-        
-        bool UnaryPathFormula::containsNextFormula() const {
-            return this->getSubformula().containsNextFormula();
-        }
-        
-        bool UnaryPathFormula::containsProbabilityOperator() const {
-            return this->getSubformula().containsProbabilityOperator();
-        }
-        
-        bool UnaryPathFormula::containsNestedProbabilityOperators() const {
-            return this->getSubformula().containsNestedProbabilityOperators();
-        }
-        
-        bool UnaryPathFormula::containsRewardOperator() const {
-            return this->getSubformula().containsRewardOperator();
-        }
-        
-        bool UnaryPathFormula::containsNestedRewardOperators() const {
-            return this->getSubformula().containsNestedRewardOperators();
-        }
-        
+
         Formula const& UnaryPathFormula::getSubformula() const {
             return *subformula;
         }
diff --git a/src/logic/UnaryPathFormula.h b/src/logic/UnaryPathFormula.h
index be60edbd9..3ea27d8f5 100644
--- a/src/logic/UnaryPathFormula.h
+++ b/src/logic/UnaryPathFormula.h
@@ -17,16 +17,6 @@ namespace storm {
 
             virtual bool isUnaryPathFormula() const override;
             
-            virtual bool isPctlPathFormula() const override;
-            virtual bool isPctlWithConditionalPathFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool containsBoundedUntilFormula() const override;
-            virtual bool containsNextFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
-            virtual bool containsRewardOperator() const override;
-            virtual bool containsNestedRewardOperators() const override;
-            
             Formula const& getSubformula() const;
             
             virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override;
diff --git a/src/logic/UnaryStateFormula.cpp b/src/logic/UnaryStateFormula.cpp
index a57b86b1e..e99c77057 100644
--- a/src/logic/UnaryStateFormula.cpp
+++ b/src/logic/UnaryStateFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/UnaryStateFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         UnaryStateFormula::UnaryStateFormula(std::shared_ptr<Formula const> subformula) : subformula(subformula) {
@@ -10,44 +12,8 @@ namespace storm {
             return true;
         }
         
-        bool UnaryStateFormula::isPropositionalFormula() const {
-            return this->getSubformula().isPropositionalFormula();
-        }
-        
-        bool UnaryStateFormula::isPctlStateFormula() const {
-            return this->getSubformula().isPctlStateFormula();
-        }
-        
-        bool UnaryStateFormula::isPctlWithConditionalStateFormula() const {
-            return this->getSubformula().isPctlWithConditionalStateFormula();
-        }
-
-        bool UnaryStateFormula::isLtlFormula() const {
-            return this->getSubformula().isLtlFormula();
-        }
-        
-        bool UnaryStateFormula::containsBoundedUntilFormula() const {
-            return this->getSubformula().containsBoundedUntilFormula();
-        }
-        
-        bool UnaryStateFormula::containsNextFormula() const {
-            return this->getSubformula().containsNextFormula();
-        }
-        
-        bool UnaryStateFormula::containsProbabilityOperator() const {
-            return getSubformula().containsProbabilityOperator();
-        }
-        
-        bool UnaryStateFormula::containsNestedProbabilityOperators() const {
-            return getSubformula().containsNestedProbabilityOperators();
-        }
-        
-        bool UnaryStateFormula::containsRewardOperator() const {
-            return this->getSubformula().containsRewardOperator();
-        }
-        
-        bool UnaryStateFormula::containsNestedRewardOperators() const {
-            return this->getSubformula().containsNestedRewardOperators();
+        boost::any UnaryStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
         }
         
         Formula const& UnaryStateFormula::getSubformula() const {
diff --git a/src/logic/UnaryStateFormula.h b/src/logic/UnaryStateFormula.h
index 8b5539a88..1dcf00023 100644
--- a/src/logic/UnaryStateFormula.h
+++ b/src/logic/UnaryStateFormula.h
@@ -15,16 +15,7 @@ namespace storm {
             
             virtual bool isUnaryStateFormula() const override;
 
-            virtual bool isPropositionalFormula() const override;
-            virtual bool isPctlWithConditionalStateFormula() const override;
-            virtual bool isPctlStateFormula() const override;
-            virtual bool isLtlFormula() const override;
-            virtual bool containsBoundedUntilFormula() const override;
-            virtual bool containsNextFormula() const override;
-            virtual bool containsProbabilityOperator() const override;
-            virtual bool containsNestedProbabilityOperators() const override;
-            virtual bool containsRewardOperator() const override;
-            virtual bool containsNestedRewardOperators() const override;
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             Formula const& getSubformula() const;
             
diff --git a/src/logic/UntilFormula.cpp b/src/logic/UntilFormula.cpp
index b15f3743f..a00eae77d 100644
--- a/src/logic/UntilFormula.cpp
+++ b/src/logic/UntilFormula.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/UntilFormula.h"
 
+#include "src/logic/FormulaVisitor.h"
+
 namespace storm {
     namespace logic {
         UntilFormula::UntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) {
@@ -10,10 +12,14 @@ namespace storm {
             return true;
         }
         
-        bool UntilFormula::isValidProbabilityPathFormula() const {
+        bool UntilFormula::isProbabilityPathFormula() const {
             return true;
         }
         
+        boost::any UntilFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
+            return visitor.visit(*this, data);
+        }
+        
         std::shared_ptr<Formula> UntilFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
             return std::make_shared<UntilFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
         }
diff --git a/src/logic/UntilFormula.h b/src/logic/UntilFormula.h
index 87ceef806..887d39b45 100644
--- a/src/logic/UntilFormula.h
+++ b/src/logic/UntilFormula.h
@@ -14,8 +14,10 @@ namespace storm {
             }
             
             virtual bool isUntilFormula() const override;
-            virtual bool isValidProbabilityPathFormula() const override;
+            virtual bool isProbabilityPathFormula() const override;
 
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
+            
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
             virtual std::ostream& writeToStream(std::ostream& out) const override;
diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index 56a65b39e..e7fabdec1 100644
--- a/src/modelchecker/AbstractModelChecker.cpp
+++ b/src/modelchecker/AbstractModelChecker.cpp
@@ -17,11 +17,15 @@ namespace storm {
             if (formula.isStateFormula()) {
                 return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula()));
             } else if (formula.isPathFormula()) {
-                if (checkTask.computeProbabilities()) {
+                if (formula.isProbabilityPathFormula()) {
                     return this->computeProbabilities(checkTask.substituteFormula(formula.asPathFormula()));
-                } else if (checkTask.computeRewards()) {
+                } else if (formula.isRewardPathFormula()) {
                     return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula()));
                 }
+            } else if (formula.isConditionalProbabilityFormula()) {
+                return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula()));
+            } else if (formula.isConditionalRewardFormula()) {
+                return this->computeConditionalRewards(checkTask.substituteFormula(formula.asConditionalFormula()));
             }
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid.");
         }
@@ -30,8 +34,6 @@ namespace storm {
             storm::logic::PathFormula const& pathFormula = checkTask.getFormula();
             if (pathFormula.isBoundedUntilFormula()) {
                 return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(pathFormula.asBoundedUntilFormula()));
-            } else if (pathFormula.isConditionalPathFormula()) {
-                return this->computeConditionalProbabilities(checkTask.substituteFormula(pathFormula.asConditionalPathFormula()));
             } else if (pathFormula.isEventuallyFormula()) {
                 return this->computeEventuallyProbabilities(checkTask.substituteFormula(pathFormula.asEventuallyFormula()));
             } else if (pathFormula.isGloballyFormula()) {
@@ -48,7 +50,7 @@ namespace storm {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
         
-        std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) {
+        std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
         
@@ -84,6 +86,10 @@ namespace storm {
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid.");
         }
         
+        std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
+            STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
+        }
+        
         std::unique_ptr<CheckResult> AbstractModelChecker::computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
@@ -171,8 +177,6 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) {
             storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula();
-            STORM_LOG_THROW(stateFormula.getSubformula().isValidProbabilityPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
-            
             std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula()));
             
             if (stateFormula.hasBound()) {
@@ -185,8 +189,6 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) {
             storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula();
-            STORM_LOG_THROW(stateFormula.getSubformula().isValidRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
-            
             std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula()));
             
             if (checkTask.isBoundSet()) {
diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h
index f827c99ff..c79302808 100644
--- a/src/modelchecker/AbstractModelChecker.h
+++ b/src/modelchecker/AbstractModelChecker.h
@@ -36,8 +36,8 @@ namespace storm {
                         
             // The methods to compute probabilities for path formulas.
             virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask);
+            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask);
-            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask);
@@ -45,6 +45,7 @@ namespace storm {
             
             // The methods to compute the rewards for path formulas.
             virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask);
+            virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask);
diff --git a/src/modelchecker/CheckTask.h b/src/modelchecker/CheckTask.h
index a780ef168..8693f09f2 100644
--- a/src/modelchecker/CheckTask.h
+++ b/src/modelchecker/CheckTask.h
@@ -63,8 +63,6 @@ namespace storm {
                         }
                     }
                 } else if (formula.isRewardOperatorFormula()) {
-                    this->checkType = CheckType::Rewards;
-                    
                     storm::logic::RewardOperatorFormula const& rewardOperatorFormula = formula.asRewardOperatorFormula();
                     this->rewardModel = rewardOperatorFormula.getOptionalRewardModelName();
                     
@@ -82,7 +80,7 @@ namespace storm {
              */
             template<typename NewFormulaType>
             CheckTask<NewFormulaType, ValueType> substituteFormula(NewFormulaType const& newFormula) const {
-                return CheckTask<NewFormulaType, ValueType>(newFormula, this->checkType, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers);
+                return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers);
             }
             
             /*!
@@ -91,27 +89,6 @@ namespace storm {
             FormulaType const& getFormula() const {
                 return formula.get();
             }
-
-            /*!
-             * Retrieves whether probabilities are to be computed.
-             */
-            bool computeProbabilities() const {
-                return checkType == CheckType::Probabilities;
-            }
-            
-            /*!
-             * Retrieves whether rewards are to be computed.
-             */
-            bool computeRewards() const {
-                return checkType == CheckType::Rewards;
-            }
-            
-            /*!
-             * Retrieves the type of this task.
-             */
-            CheckType getCheckType() const {
-                return checkType;
-            }
             
             /*!
              * Retrieves whether an optimization direction was set.
@@ -211,7 +188,6 @@ namespace storm {
              * Creates a task object with the given options.
              *
              * @param formula The formula to attach to the task.
-             * @param checkType The type of task: whether to compute probabilities or rewards.
              * @param optimizationDirection If set, the probabilities will be minimized/maximized.
              * @param rewardModelName If given, the checking has to be done wrt. to this reward model.
              * @param onlyInitialStatesRelevant If set to true, the model checker may decide to only compute the values
@@ -222,16 +198,13 @@ namespace storm {
              * @param produceSchedulers If supported by the model checker and the model formalism, schedulers to achieve
              * a value will be produced if this flag is set.
              */
-            CheckTask(std::reference_wrapper<FormulaType const> const& formula, CheckType checkType, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), checkType(checkType), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) {
+            CheckTask(std::reference_wrapper<FormulaType const> const& formula, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) {
                 // Intentionally left empty.
             }
             
             // The formula that is to be checked.
             std::reference_wrapper<FormulaType const> formula;
             
-            // A type indicating whether probabilities or rewards are to be computed.
-            CheckType checkType;
-            
             // If set, the probabilities will be minimized/maximized.
             boost::optional<storm::OptimizationDirection> optimizationDirection;
 

From dc8a5b11e0df6ff5238f8abd906cf85ed41989ae Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 18 Feb 2016 18:04:15 +0100
Subject: [PATCH 04/23] more refactoring regarding fragment checking

Former-commit-id: fd335f6f8edd73577910525ff03134d0121aba21
---
 src/logic/Formula.cpp                         |  17 ++
 src/logic/Formula.h                           |  12 +-
 src/logic/FormulaInformation.cpp              |  46 +++++
 src/logic/FormulaInformation.h                |  29 +++
 src/logic/FormulaInformationVisitor.cpp       |  85 +++++++++
 src/logic/FormulaInformationVisitor.h         |  38 ++++
 src/logic/FragmentChecker.cpp                 | 165 +++++++++++++-----
 src/logic/FragmentSpecification.cpp           | 148 ++++++++++++++++
 src/logic/FragmentSpecification.h             |  43 ++++-
 src/logic/RewardOperatorFormula.cpp           |   4 +
 src/logic/UnaryStateFormula.cpp               |   4 -
 src/logic/UnaryStateFormula.h                 |   2 -
 .../csl/HybridCtmcCslModelChecker.cpp         |   4 +-
 .../csl/SparseCtmcCslModelChecker.cpp         |   4 +-
 .../SparseMarkovAutomatonCslModelChecker.cpp  |   6 +-
 .../prctl/HybridDtmcPrctlModelChecker.cpp     |   4 +-
 .../prctl/HybridMdpPrctlModelChecker.cpp      |  13 +-
 .../prctl/SparseDtmcPrctlModelChecker.cpp     |  31 +---
 .../prctl/SparseDtmcPrctlModelChecker.h       |   2 +-
 .../prctl/SparseMdpPrctlModelChecker.cpp      |  31 +---
 .../prctl/SparseMdpPrctlModelChecker.h        |   2 +-
 .../prctl/SymbolicDtmcPrctlModelChecker.cpp   |  14 +-
 .../prctl/SymbolicMdpPrctlModelChecker.cpp    |  13 +-
 .../SparsePropositionalModelChecker.cpp       |   4 +-
 .../SymbolicPropositionalModelChecker.cpp     |   4 +-
 .../SparseDtmcEliminationModelChecker.cpp     |  58 ++----
 .../SparseDtmcEliminationModelChecker.h       |   2 +-
 src/parser/FormulaParser.cpp                  |  24 +--
 .../BisimulationDecomposition.cpp             |  21 ++-
 test/functional/logic/FragmentCheckerTest.cpp |  14 ++
 test/functional/parser/FormulaParserTest.cpp  |  11 +-
 31 files changed, 653 insertions(+), 202 deletions(-)
 create mode 100644 src/logic/FormulaInformation.cpp
 create mode 100644 src/logic/FormulaInformation.h
 create mode 100644 src/logic/FormulaInformationVisitor.cpp
 create mode 100644 src/logic/FormulaInformationVisitor.h
 create mode 100644 test/functional/logic/FragmentCheckerTest.cpp

diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp
index 6270d5664..d682d02aa 100644
--- a/src/logic/Formula.cpp
+++ b/src/logic/Formula.cpp
@@ -1,6 +1,9 @@
 #include "src/logic/Formulas.h"
 #include <sstream>
 
+#include "src/logic/FragmentChecker.h"
+#include "src/logic/FormulaInformationVisitor.h"
+
 namespace storm {
     namespace logic {
         bool Formula::isPathFormula() const {
@@ -111,6 +114,10 @@ namespace storm {
             return false;
         }
         
+        bool Formula::isReachabilityRewardFormula() const {
+            return false;
+        }
+        
         bool Formula::isLongRunAverageRewardFormula() const {
             return false;
         }
@@ -131,6 +138,16 @@ namespace storm {
             return false;
         }
         
+        bool Formula::isInFragment(FragmentSpecification const& fragment) const {
+            FragmentChecker checker;
+            return checker.conformsToSpecification(*this, fragment);
+        }
+        
+        FormulaInformation Formula::info() const {
+            FormulaInformationVisitor visitor;
+            return visitor.getInformation(*this);
+        }
+        
         std::shared_ptr<Formula const> Formula::getTrueFormula() {
             return std::shared_ptr<Formula const>(new BooleanLiteralFormula(true));
         }
diff --git a/src/logic/Formula.h b/src/logic/Formula.h
index ae879fce6..f2e06bc0b 100644
--- a/src/logic/Formula.h
+++ b/src/logic/Formula.h
@@ -19,8 +19,11 @@ namespace storm {
         // Forward-declare visitor for accept() method.
         class FormulaVisitor;
 
-        // Also foward-declare base model checker class.
-        class ModelChecker;
+        // Forward-declare fragment specification for isInFragment() method.
+        class FragmentSpecification;
+        
+        // Forward-declare formula information class for info() method.
+        class FormulaInformation;
         
         class Formula : public std::enable_shared_from_this<Formula const> {
         public:
@@ -80,7 +83,10 @@ namespace storm {
             virtual bool isUnaryPathFormula() const;
             virtual bool isUnaryStateFormula() const;
 
-            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const = 0;
+            bool isInFragment(FragmentSpecification const& fragment) const;
+            FormulaInformation info() const;
+            
+            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data = boost::any()) const = 0;
             
             static std::shared_ptr<Formula const> getTrueFormula();
             
diff --git a/src/logic/FormulaInformation.cpp b/src/logic/FormulaInformation.cpp
new file mode 100644
index 000000000..b49f4a23b
--- /dev/null
+++ b/src/logic/FormulaInformation.cpp
@@ -0,0 +1,46 @@
+#include "src/logic/FormulaInformation.h"
+
+namespace storm {
+    namespace logic {
+        FormulaInformation::FormulaInformation() {
+            this->mContainsRewardOperator = false;
+            this->mContainsNextFormula = false;
+            this->mContainsBoundedUntilFormula = false;
+        }
+        
+        bool FormulaInformation::containsRewardOperator() const {
+            return this->mContainsRewardOperator;
+        }
+        
+        bool FormulaInformation::containsNextFormula() const {
+            return this->mContainsNextFormula;
+        }
+        
+        bool FormulaInformation::containsBoundedUntilFormula() const {
+            return this-mContainsBoundedUntilFormula;
+        }
+        
+        FormulaInformation FormulaInformation::join(FormulaInformation const& other) {
+            FormulaInformation result;
+            result.mContainsRewardOperator = this->containsRewardOperator() || other.containsRewardOperator();
+            result.mContainsNextFormula = this->containsNextFormula() || other.containsNextFormula();
+            result.mContainsBoundedUntilFormula = this->containsBoundedUntilFormula() || other.containsBoundedUntilFormula();
+            return result;
+        }
+        
+        FormulaInformation& FormulaInformation::setContainsRewardOperator(bool newValue) {
+            this->mContainsRewardOperator = newValue;
+            return *this;
+        }
+        
+        FormulaInformation& FormulaInformation::setContainsNextFormula(bool newValue) {
+            this->mContainsNextFormula = newValue;
+            return *this;
+        }
+        
+        FormulaInformation& FormulaInformation::setContainsBoundedUntilFormula(bool newValue) {
+            this->mContainsBoundedUntilFormula = newValue;
+            return *this;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/logic/FormulaInformation.h b/src/logic/FormulaInformation.h
new file mode 100644
index 000000000..53269696c
--- /dev/null
+++ b/src/logic/FormulaInformation.h
@@ -0,0 +1,29 @@
+#ifndef STORM_LOGIC_FORMULAINFORMATION_H_
+#define STORM_LOGIC_FORMULAINFORMATION_H_
+
+namespace storm {
+    namespace logic {
+        
+        class FormulaInformation {
+        public:
+            FormulaInformation();
+            bool containsRewardOperator() const;
+            bool containsNextFormula() const;
+            bool containsBoundedUntilFormula() const;
+            
+            FormulaInformation join(FormulaInformation const& other);
+            
+            FormulaInformation& setContainsRewardOperator(bool newValue = true);
+            FormulaInformation& setContainsNextFormula(bool newValue = true);
+            FormulaInformation& setContainsBoundedUntilFormula(bool newValue = true);
+            
+        private:
+            bool mContainsRewardOperator;
+            bool mContainsNextFormula;
+            bool mContainsBoundedUntilFormula;
+        };
+        
+    }
+}
+
+#endif /* STORM_LOGIC_FORMULAINFORMATION_H_ */
\ No newline at end of file
diff --git a/src/logic/FormulaInformationVisitor.cpp b/src/logic/FormulaInformationVisitor.cpp
new file mode 100644
index 000000000..f8ef57f92
--- /dev/null
+++ b/src/logic/FormulaInformationVisitor.cpp
@@ -0,0 +1,85 @@
+#include "src/logic/FormulaInformationVisitor.h"
+
+#include "src/logic/Formulas.h"
+
+namespace storm {
+    namespace logic {
+        FormulaInformation FormulaInformationVisitor::getInformation(Formula const& f) const {
+            boost::any result = f.accept(*this, boost::any());
+            return boost::any_cast<FormulaInformation>(result);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(AtomicLabelFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(BooleanLiteralFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const {
+            return boost::any_cast<FormulaInformation>(f.getLeftSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getRightSubformula().accept(*this))).setContainsBoundedUntilFormula();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(ConditionalFormula const& f, boost::any const& data) const {
+            return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getConditionFormula().accept(*this)));
+        }
+        
+        boost::any FormulaInformationVisitor::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(EventuallyFormula const& f, boost::any const& data) const {
+            return f.getSubformula().accept(*this);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const {
+            return f.getSubformula().accept(*this);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(GloballyFormula const& f, boost::any const& data) const {
+            return f.getSubformula().accept(*this);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
+            return f.getSubformula().accept(*this);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
+            return FormulaInformation();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(NextFormula const& f, boost::any const& data) const {
+            return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).setContainsNextFormula();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
+            return f.getSubformula().accept(*this);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const {
+            return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).setContainsRewardOperator();
+        }
+        
+        boost::any FormulaInformationVisitor::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const {
+            return f.getSubformula().accept(*this);
+        }
+        
+        boost::any FormulaInformationVisitor::visit(UntilFormula const& f, boost::any const& data) const {
+            return boost::any_cast<FormulaInformation>(f.getLeftSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getRightSubformula().accept(*this)));
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/logic/FormulaInformationVisitor.h b/src/logic/FormulaInformationVisitor.h
new file mode 100644
index 000000000..2e2cc0d6d
--- /dev/null
+++ b/src/logic/FormulaInformationVisitor.h
@@ -0,0 +1,38 @@
+#ifndef STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_
+#define STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_
+
+#include "src/logic/FormulaVisitor.h"
+#include "src/logic/FormulaInformation.h"
+
+namespace storm {
+    namespace logic {
+        
+        class FormulaInformationVisitor : public FormulaVisitor {
+        public:
+            FormulaInformation getInformation(Formula const& f) const;
+            
+            virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(NextFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const override;
+            virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override;
+        };
+        
+    }
+}
+
+
+#endif /* STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_ */
\ No newline at end of file
diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp
index d94056f58..405b75a27 100644
--- a/src/logic/FragmentChecker.cpp
+++ b/src/logic/FragmentChecker.cpp
@@ -4,49 +4,75 @@
 
 namespace storm {
     namespace logic {
+        class InheritedInformation {
+        public:
+            InheritedInformation(FragmentSpecification const& fragmentSpecification) : fragmentSpecification(fragmentSpecification) {
+                // Intentionally left empty.
+            }
+            
+            FragmentSpecification const& getSpecification() const {
+                return fragmentSpecification;
+            }
+
+        private:
+            FragmentSpecification const& fragmentSpecification;
+        };
+        
         bool FragmentChecker::conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const {
-            boost::any result = f.accept(*this, specification);
+            boost::any result = f.accept(*this, InheritedInformation(specification));
             return boost::any_cast<bool>(result);
         }
         
         boost::any FragmentChecker::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areAtomicExpressionFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            return inherited.getSpecification().areAtomicExpressionFormulasAllowed();
         }
         
         boost::any FragmentChecker::visit(AtomicLabelFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areAtomicLabelFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            return inherited.getSpecification().areAtomicLabelFormulasAllowed();
         }
         
         boost::any FragmentChecker::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            bool result = specification.areBinaryBooleanStateFormulasAllowed();
-            result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, specification));
-            result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, specification));
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areBinaryBooleanStateFormulasAllowed();
+            result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
+            result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
             return result;
         }
         
         boost::any FragmentChecker::visit(BooleanLiteralFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areBooleanLiteralFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            return inherited.getSpecification().areBooleanLiteralFormulasAllowed();
         }
         
         boost::any FragmentChecker::visit(BoundedUntilFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            bool result = specification.areBoundedUntilFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areBoundedUntilFormulasAllowed();
+            if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
+                result = result && !f.getLeftSubformula().isPathFormula();
+                result = result && !f.getRightSubformula().isPathFormula();
+            }
+            if (f.hasDiscreteTimeBound()) {
+                result = result && inherited.getSpecification().areStepBoundedUntilFormulasAllowed();
+            } else {
+                result = result && inherited.getSpecification().areTimeBoundedUntilFormulasAllowed();
+            }
             result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
             result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
             return result;
         }
         
         boost::any FragmentChecker::visit(ConditionalFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
             bool result = true;
             if (f.isConditionalProbabilityFormula()) {
-                result &= specification.areConditionalProbabilityFormulasAllowed();
+                result = result && inherited.getSpecification().areConditionalProbabilityFormulasAllowed();
             } else if (f.Formula::isConditionalRewardFormula()) {
-                result &= specification.areConditionalRewardFormulasFormulasAllowed();
+                result = result && inherited.getSpecification().areConditionalRewardFormulasFormulasAllowed();
+            }
+            if (inherited.getSpecification().areOnlyEventuallyFormuluasInConditionalFormulasAllowed()) {
+                result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula();
             }
             result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data));
@@ -54,65 +80,124 @@ namespace storm {
         }
         
         boost::any FragmentChecker::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areCumulativeRewardFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            return inherited.getSpecification().areCumulativeRewardFormulasAllowed();
         }
         
         boost::any FragmentChecker::visit(EventuallyFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            bool result = specification.areEventuallyFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = true;
+            if (f.isEventuallyFormula()) {
+                result = inherited.getSpecification().areEventuallyFormulasAllowed();
+                if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
+                    result = result && !f.getSubformula().isPathFormula();
+                }
+            } else if (f.isReachabilityRewardFormula()) {
+                result = result && inherited.getSpecification().areReachabilityRewardFormulasAllowed();
+                result = result && f.getSubformula().isStateFormula();
+            } else if (f.isReachbilityExpectedTimeFormula()) {
+                result = result && inherited.getSpecification().areReachbilityExpectedTimeFormulasAllowed();
+                result = result && f.getSubformula().isStateFormula();
+            }
             result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             return result;
         }
         
         boost::any FragmentChecker::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areExpectedTimeOperatorsAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areExpectedTimeOperatorsAllowed();
+            result = result && f.getSubformula().isExpectedTimePathFormula();
+            if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+            } else {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            }
+            return result;
         }
         
         boost::any FragmentChecker::visit(GloballyFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areGloballyFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areGloballyFormulasAllowed();
+            if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
+                result = result && !f.getSubformula().isPathFormula();
+            }
+            result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            return result;
         }
         
         boost::any FragmentChecker::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areInstantaneousRewardFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            return inherited.getSpecification().areInstantaneousRewardFormulasAllowed();
         }
         
         boost::any FragmentChecker::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areLongRunAverageOperatorsAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areLongRunAverageOperatorsAllowed();
+            result = result && f.getSubformula().isStateFormula();
+            if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+            } else {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            }
+            return result;
         }
         
         boost::any FragmentChecker::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areLongRunAverageRewardFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            return inherited.getSpecification().areLongRunAverageRewardFormulasAllowed();
         }
         
         boost::any FragmentChecker::visit(NextFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areNextFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areNextFormulasAllowed();
+            if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
+                result = result && !f.getSubformula().isPathFormula();
+            }
+            result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            return result;
         }
         
         boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areProbabilityOperatorsAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areProbabilityOperatorsAllowed();
+            result = result && f.getSubformula().isProbabilityPathFormula();
+            if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+            } else {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            }
+            return result;
         }
         
         boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areRewardOperatorsAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areRewardOperatorsAllowed();
+            result = result && f.getSubformula().isRewardPathFormula();
+            if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+            } else {
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            }
+            return result;
         }
         
         boost::any FragmentChecker::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areUnaryBooleanStateFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areUnaryBooleanStateFormulasAllowed();
+            result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            return result;
         }
         
         boost::any FragmentChecker::visit(UntilFormula const& f, boost::any const& data) const {
-            FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data);
-            return specification.areUntilFormulasAllowed();
+            InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
+            bool result = inherited.getSpecification().areUntilFormulasAllowed();
+            if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
+                result = result && !f.getLeftSubformula().isPathFormula();
+                result = result && !f.getRightSubformula().isPathFormula();
+            }
+            result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
+            result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
+            return result;
         }
     }
 }
\ No newline at end of file
diff --git a/src/logic/FragmentSpecification.cpp b/src/logic/FragmentSpecification.cpp
index eeb697582..d8c02a18e 100644
--- a/src/logic/FragmentSpecification.cpp
+++ b/src/logic/FragmentSpecification.cpp
@@ -3,6 +3,99 @@
 namespace storm {
     namespace logic {
         
+        FragmentSpecification propositional() {
+            FragmentSpecification propositional;
+            
+            propositional.setBooleanLiteralFormulasAllowed(true);
+            propositional.setBinaryBooleanStateFormulasAllowed(true);
+            propositional.setUnaryBooleanStateFormulasAllowed(true);
+            propositional.setAtomicExpressionFormulasAllowed(true);
+            propositional.setAtomicLabelFormulasAllowed(true);
+            
+            return propositional;
+        }
+        
+        FragmentSpecification pctl() {
+            FragmentSpecification pctl = propositional();
+            
+            pctl.setProbabilityOperatorsAllowed(true);
+            pctl.setGloballyFormulasAllowed(true);
+            pctl.setEventuallyFormulasAllowed(true);
+            pctl.setNextFormulasAllowed(true);
+            pctl.setUntilFormulasAllowed(true);
+            pctl.setBoundedUntilFormulasAllowed(true);
+            pctl.setStepBoundedUntilFormulasAllowed(true);
+            
+            return pctl;
+        }
+        
+        FragmentSpecification prctl() {
+            FragmentSpecification prctl = pctl();
+            
+            prctl.setRewardOperatorsAllowed(true);
+            prctl.setCumulativeRewardFormulasAllowed(true);
+            prctl.setInstantaneousFormulasAllowed(true);
+            prctl.setReachabilityRewardFormulasAllowed(true);
+            prctl.setLongRunAverageOperatorsAllowed(true);
+            
+            return prctl;
+        }
+        
+        FragmentSpecification csl() {
+            FragmentSpecification csl = pctl();
+            
+            csl.setTimeBoundedUntilFormulasAllowed(true);
+            
+            return csl;
+        }
+        
+        FragmentSpecification csrl() {
+            FragmentSpecification csrl;
+            
+            csrl.setRewardOperatorsAllowed(true);
+            csrl.setCumulativeRewardFormulasAllowed(true);
+            csrl.setInstantaneousFormulasAllowed(true);
+            csrl.setReachabilityRewardFormulasAllowed(true);
+            csrl.setLongRunAverageOperatorsAllowed(true);
+            
+            return csrl;
+        }
+        
+        FragmentSpecification::FragmentSpecification() {
+            probabilityOperator = false;
+            rewardOperator = false;
+            expectedTimeOperator = false;
+            longRunAverageOperator = false;
+            
+            globallyFormula = false;
+            eventuallyFormula = false;
+            nextFormula = false;
+            untilFormula = false;
+            boundedUntilFormula = false;
+            
+            atomicExpressionFormula = false;
+            atomicLabelFormula = false;
+            booleanLiteralFormula = false;
+            unaryBooleanStateFormula = false;
+            binaryBooleanStateFormula = false;
+            
+            cumulativeRewardFormula = false;
+            instantaneousRewardFormula = false;
+            reachabilityRewardFormula = false;
+            longRunAverageRewardFormula = false;
+            
+            conditionalProbabilityFormula = false;
+            conditionalRewardFormula = false;
+            
+            reachabilityExpectedTimeFormula = false;
+            
+            nestedOperators = true;
+            nestedPathFormulas = false;
+            onlyEventuallyFormuluasInConditionalFormulas = true;
+            stepBoundedUntilFormulas = false;
+            timeBoundedUntilFormulas = false;
+        }
+        
         FragmentSpecification FragmentSpecification::copy() const {
             return FragmentSpecification(*this);
         }
@@ -205,5 +298,60 @@ namespace storm {
             return *this;
         }
         
+        bool FragmentSpecification::areNestedPathFormulasAllowed() const {
+            return this->nestedPathFormulas;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setNestedPathFormulasAllowed(bool newValue) {
+            this->nestedPathFormulas = newValue;
+            return *this;
+        }
+
+        bool FragmentSpecification::areOnlyEventuallyFormuluasInConditionalFormulasAllowed() const {
+            return this->onlyEventuallyFormuluasInConditionalFormulas;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setOnlyEventuallyFormuluasInConditionalFormulasAllowed(bool newValue) {
+            this->onlyEventuallyFormuluasInConditionalFormulas = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areStepBoundedUntilFormulasAllowed() const {
+            return this->stepBoundedUntilFormulas;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setStepBoundedUntilFormulasAllowed(bool newValue) {
+            this->stepBoundedUntilFormulas = newValue;
+            return *this;
+        }
+        
+        bool FragmentSpecification::areTimeBoundedUntilFormulasAllowed() const {
+            return this->timeBoundedUntilFormulas;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setTimeBoundedUntilFormulasAllowed(bool newValue) {
+            this->timeBoundedUntilFormulas = newValue;
+            return *this;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setOperatorsAllowed(bool newValue) {
+            this->setProbabilityOperatorsAllowed(newValue);
+            this->setRewardOperatorsAllowed(newValue);
+            this->setLongRunAverageOperatorsAllowed(newValue);
+            this->setExpectedTimeOperatorsAllowed(newValue);
+            return *this;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setExpectedTimeAllowed(bool newValue) {
+            this->setExpectedTimeOperatorsAllowed(newValue);
+            this->setReachbilityExpectedTimeFormulasAllowed(newValue);
+            return *this;
+        }
+        
+        FragmentSpecification& FragmentSpecification::setLongRunAverageProbabilitiesAllowed(bool newValue) {
+            this->setLongRunAverageOperatorsAllowed(newValue);
+            return *this;
+        }
+        
     }
 }
\ No newline at end of file
diff --git a/src/logic/FragmentSpecification.h b/src/logic/FragmentSpecification.h
index 91099703f..1bd46f4f7 100644
--- a/src/logic/FragmentSpecification.h
+++ b/src/logic/FragmentSpecification.h
@@ -5,6 +5,12 @@ namespace storm {
     namespace logic {
         class FragmentSpecification {
         public:
+            FragmentSpecification();
+            FragmentSpecification(FragmentSpecification const& other) = default;
+            FragmentSpecification(FragmentSpecification&& other) = default;
+            FragmentSpecification& operator=(FragmentSpecification const& other) = default;
+            FragmentSpecification& operator=(FragmentSpecification&& other) = default;
+            
             FragmentSpecification copy() const;
             
             bool areProbabilityOperatorsAllowed() const;
@@ -73,6 +79,22 @@ namespace storm {
             bool areNestedOperatorsAllowed() const;
             FragmentSpecification& setNestedOperatorsAllowed(bool newValue);
 
+            bool areNestedPathFormulasAllowed() const;
+            FragmentSpecification& setNestedPathFormulasAllowed(bool newValue);
+            
+            bool areOnlyEventuallyFormuluasInConditionalFormulasAllowed() const;
+            FragmentSpecification& setOnlyEventuallyFormuluasInConditionalFormulasAllowed(bool newValue);
+
+            bool areStepBoundedUntilFormulasAllowed() const;
+            FragmentSpecification& setStepBoundedUntilFormulasAllowed(bool newValue);
+            
+            bool areTimeBoundedUntilFormulasAllowed() const;
+            FragmentSpecification& setTimeBoundedUntilFormulasAllowed(bool newValue);
+            
+            FragmentSpecification& setOperatorsAllowed(bool newValue);
+            FragmentSpecification& setExpectedTimeAllowed(bool newValue);
+            FragmentSpecification& setLongRunAverageProbabilitiesAllowed(bool newValue);
+            
         private:
             // Flags that indicate whether it is legal to see such a formula.
             bool probabilityOperator;
@@ -104,8 +126,27 @@ namespace storm {
             
             // Members that indicate certain restrictions.
             bool nestedOperators;
-            
+            bool nestedPathFormulas;
+            bool onlyEventuallyFormuluasInConditionalFormulas;
+            bool stepBoundedUntilFormulas;
+            bool timeBoundedUntilFormulas;
         };
+        
+        // Propositional.
+        FragmentSpecification propositional();
+        
+        // Regular PCTL.
+        FragmentSpecification pctl();
+        
+        // PCTL + cumulative, instantaneous, reachability and long-run rewards.
+        FragmentSpecification prctl();
+        
+        // Regular CSL.
+        FragmentSpecification csl();
+        
+        // CSL + cumulative, instantaneous, reachability and long-run rewards.
+        FragmentSpecification csrl();
+
     }
 }
 
diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp
index 0e025c208..711f78789 100644
--- a/src/logic/RewardOperatorFormula.cpp
+++ b/src/logic/RewardOperatorFormula.cpp
@@ -32,6 +32,10 @@ namespace storm {
             return this->rewardModelName.get();
         }
         
+        bool RewardOperatorFormula::hasRewardModelName() const {
+            return static_cast<bool>(rewardModelName);
+        }
+        
         boost::optional<std::string> const& RewardOperatorFormula::getOptionalRewardModelName() const {
             return this->rewardModelName;
         }
diff --git a/src/logic/UnaryStateFormula.cpp b/src/logic/UnaryStateFormula.cpp
index e99c77057..3ff75a0e1 100644
--- a/src/logic/UnaryStateFormula.cpp
+++ b/src/logic/UnaryStateFormula.cpp
@@ -12,10 +12,6 @@ namespace storm {
             return true;
         }
         
-        boost::any UnaryStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
-            return visitor.visit(*this, data);
-        }
-        
         Formula const& UnaryStateFormula::getSubformula() const {
             return *subformula;
         }
diff --git a/src/logic/UnaryStateFormula.h b/src/logic/UnaryStateFormula.h
index 1dcf00023..29149ebc8 100644
--- a/src/logic/UnaryStateFormula.h
+++ b/src/logic/UnaryStateFormula.h
@@ -14,8 +14,6 @@ namespace storm {
             }
             
             virtual bool isUnaryStateFormula() const override;
-
-            virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
             
             Formula const& getSubformula() const;
             
diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
index c6b7c9d1e..a08d7a6b1 100644
--- a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
+++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
@@ -10,6 +10,8 @@
 #include "src/storage/dd/Add.h"
 #include "src/storage/dd/Bdd.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 namespace storm {
     namespace modelchecker {
         template<storm::dd::DdType DdType, class ValueType>
@@ -25,7 +27,7 @@ namespace storm {
         template<storm::dd::DdType DdType, class ValueType>
         bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslFormula() || formula.isRewardFormula();
+            return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true));
         }
                 
         template<storm::dd::DdType DdType, class ValueType>
diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
index e91547e81..ee545cb27 100644
--- a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
+++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
@@ -13,6 +13,8 @@
 #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
 #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/exceptions/InvalidStateException.h"
 #include "src/exceptions/InvalidPropertyException.h"
 #include "src/exceptions/NotImplementedException.h"
@@ -32,7 +34,7 @@ namespace storm {
         template <typename SparseCtmcModelType>
         bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslStateFormula() || formula.isCslPathFormula();
+            return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true));
         }
         
         template <typename SparseCtmcModelType>
diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
index b5966bf4c..9892eb530 100644
--- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
+++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
@@ -12,6 +12,8 @@
 #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
 #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/exceptions/InvalidPropertyException.h"
 #include "src/exceptions/NotImplementedException.h"
 
@@ -30,7 +32,9 @@ namespace storm {
         template<typename SparseMarkovAutomatonModelType>
         bool SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isCslStateFormula() || formula.isCslPathFormula();
+            storm::logic::FragmentSpecification fragment = storm::logic::csl().setGloballyFormulasAllowed(false).setNextFormulasAllowed(false).setReachabilityRewardFormulasAllowed(true);
+            fragment.setExpectedTimeAllowed(true).setLongRunAverageProbabilitiesAllowed(true);
+            return formula.isInFragment(fragment);
         }
         
         template<typename SparseMarkovAutomatonModelType>
diff --git a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
index b9b0bec0a..31628f4ed 100644
--- a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
@@ -17,6 +17,8 @@
 #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
 #include "src/modelchecker/results/HybridQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/exceptions/InvalidStateException.h"
 #include "src/exceptions/InvalidPropertyException.h"
 #include "src/exceptions/InvalidArgumentException.h"
@@ -36,7 +38,7 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool HybridDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isPctlStateFormula() || formula.isPctlPathFormula();
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true));
         }
                 
         template<storm::dd::DdType DdType, typename ValueType>
diff --git a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
index cd39e8c62..f79bbb933 100644
--- a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
@@ -8,6 +8,8 @@
 #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
 #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/solver/MinMaxLinearEquationSolver.h"
 
 #include "src/settings/modules/GeneralSettings.h"
@@ -30,16 +32,7 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool HybridMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
-                return true;
-            }
-            if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
-            }
-            if (formula.isGloballyFormula()) {
-                return true;
-            }
-            return false;
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false));
         }
                 
         template<storm::dd::DdType DdType, typename ValueType>
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
index dce8a8138..df7f1ee9a 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
@@ -11,6 +11,8 @@
 #include "src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h"
 #include "src/modelchecker/csl/helper/SparseCtmcCslHelper.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/models/sparse/StandardRewardModel.h"
 
 #include "src/settings/modules/GeneralSettings.h"
@@ -34,22 +36,7 @@ namespace storm {
         template<typename SparseDtmcModelType>
         bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
-                return true;
-            }
-            if (formula.isGloballyFormula()) {
-                return true;
-            }
-            if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
-            }
-            if (formula.isConditionalPathFormula()) {
-                storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
-                if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) {
-                    return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula());
-                }
-            }
-            return false;
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true));
         }
         
         template<typename SparseDtmcModelType>
@@ -129,13 +116,13 @@ namespace storm {
         }
         
         template<typename SparseDtmcModelType>
-        std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) {
-            storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula();
-            STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
-            STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
+        std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
+            storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
+            STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
+            STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
 
-            std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula());
-            std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula());
+            std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula());
+            std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
             ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
             ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
 
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
index acc7d9283..264f1725d 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
@@ -24,7 +24,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
index a7a56a890..614522e01 100644
--- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
@@ -8,6 +8,8 @@
 #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
 #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/models/sparse/StandardRewardModel.h"
 
 #include "src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h"
@@ -39,22 +41,7 @@ namespace storm {
         template<typename SparseMdpModelType>
         bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
-                return true;
-            }
-            if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
-            }
-            if (formula.isGloballyFormula()) {
-                return true;
-            }
-            if (formula.isConditionalPathFormula()) {
-                storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
-                if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) {
-                    return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula());
-                }
-            }
-            return false;
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true));
         }
         
         template<typename SparseMdpModelType>
@@ -106,15 +93,15 @@ namespace storm {
         }
         
         template<typename SparseMdpModelType>
-        std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) {
-            storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
+            storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
             STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
             STORM_LOG_THROW(this->getModel().getInitialStates().getNumberOfSetBits() == 1, storm::exceptions::InvalidPropertyException, "Cannot compute conditional probabilities on MDPs with more than one initial state.");
-            STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
-            STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
+            STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
+            STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
 
-            std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula());
-            std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula());
+            std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula());
+            std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
             ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
             ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
 
diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
index 37cd6ef5b..b08c9abc5 100644
--- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
@@ -22,7 +22,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
diff --git a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
index 2394a3176..311ef7590 100644
--- a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
@@ -10,6 +10,9 @@
 
 #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
 #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
+
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/solver/SymbolicLinearEquationSolver.h"
 
 #include "src/settings/modules/GeneralSettings.h"
@@ -32,16 +35,7 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool SymbolicDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
-                return true;
-            }
-            if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
-            }
-            if (formula.isGloballyFormula()) {
-                return true;
-            }
-            return false;
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false));
         }
         
         template<storm::dd::DdType DdType, typename ValueType>
diff --git a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
index 9b74594dc..d6a3554e3 100644
--- a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
@@ -5,6 +5,8 @@
 #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
 #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/models/symbolic/StandardRewardModel.h"
 
 #include "src/utility/macros.h"
@@ -32,16 +34,7 @@ namespace storm {
         template<storm::dd::DdType DdType, typename ValueType>
         bool SymbolicMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) {
-                return true;
-            }
-            if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
-            }
-            if (formula.isGloballyFormula()) {
-                return true;
-            }
-            return false;
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false));
         }
         
         template<storm::dd::DdType DdType, typename ValueType>
diff --git a/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp b/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp
index f56843aef..aa947c8cb 100644
--- a/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp
+++ b/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp
@@ -10,6 +10,8 @@
 
 #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/utility/macros.h"
 #include "src/exceptions/InvalidPropertyException.h"
 
@@ -23,7 +25,7 @@ namespace storm {
         template<typename SparseModelType>
         bool SparsePropositionalModelChecker<SparseModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isPropositionalFormula();
+            return formula.isInFragment(storm::logic::propositional());
         }
         
         template<typename SparseModelType>
diff --git a/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp b/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp
index 943ecf7db..eee71e3c8 100644
--- a/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp
+++ b/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp
@@ -10,6 +10,8 @@
 
 #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/utility/macros.h"
 #include "src/exceptions/InvalidPropertyException.h"
 
@@ -23,7 +25,7 @@ namespace storm {
         template<storm::dd::DdType Type, typename ValueType>
         bool SymbolicPropositionalModelChecker<Type, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isPropositionalFormula();
+            return formula.isInFragment(storm::logic::propositional());
         }
         
         template<storm::dd::DdType Type, typename ValueType>
diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
index 98afe49a1..7022b92c8 100644
--- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
+++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
@@ -16,6 +16,8 @@
 #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
 #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
 
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/utility/graph.h"
 #include "src/utility/vector.h"
 #include "src/utility/macros.h"
@@ -82,45 +84,9 @@ namespace storm {
         template<typename SparseDtmcModelType>
         bool SparseDtmcEliminationModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            if (formula.isProbabilityOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula()));
-            } else if (formula.isRewardOperatorFormula()) {
-                return this->canHandle(checkTask.substituteFormula(formula.asRewardOperatorFormula().getSubformula()));
-            } else if (formula.isUntilFormula() || formula.isEventuallyFormula()) {
-                if (formula.isUntilFormula()) {
-                    storm::logic::UntilFormula const& untilFormula = formula.asUntilFormula();
-                    if (untilFormula.getLeftSubformula().isPropositionalFormula() && untilFormula.getRightSubformula().isPropositionalFormula()) {
-                        return true;
-                    }
-                } else if (formula.isEventuallyFormula()) {
-                    storm::logic::EventuallyFormula const& eventuallyFormula = formula.asEventuallyFormula();
-                    if (eventuallyFormula.getSubformula().isPropositionalFormula()) {
-                        return true;
-                    }
-                }
-            } else if (formula.isBoundedUntilFormula()) {
-                storm::logic::BoundedUntilFormula const& boundedUntilFormula = formula.asBoundedUntilFormula();
-                if (boundedUntilFormula.getLeftSubformula().isPropositionalFormula() && boundedUntilFormula.getRightSubformula().isPropositionalFormula()) {
-                    return true;
-                }
-            } else if (formula.isConditionalPathFormula()) {
-                storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
-                if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) {
-                    return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula());
-                }
-            } else if (formula.isLongRunAverageOperatorFormula()) {
-                storm::logic::LongRunAverageOperatorFormula const& longRunAverageOperatorFormula = formula.asLongRunAverageOperatorFormula();
-                if (longRunAverageOperatorFormula.getSubformula().isPropositionalFormula()) {
-                    return true;
-                }
-            } else if (formula.isLongRunAverageRewardFormula()) {
-                return true;
-            }
-            
-            else if (formula.isPropositionalFormula()) {
-                return true;
-            }
-            return false;
+            storm::logic::FragmentSpecification fragment = storm::logic::prctl().setCumulativeRewardFormulasAllowed(false).setInstantaneousFormulasAllowed(false);
+            fragment.setNestedOperatorsAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true);
+            return formula.isInFragment(fragment);
         }
         
         template<typename SparseDtmcModelType>
@@ -646,15 +612,15 @@ namespace storm {
         }
         
         template<typename SparseDtmcModelType>
-        std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) {
-            storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula();
+        std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
+            storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
             
             // Retrieve the appropriate bitvectors by model checking the subformulas.
-            STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula.");
-            STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula.");
+            STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula.");
+            STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula.");
             
-            std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula());
-            std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula());
+            std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula());
+            std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
             storm::storage::BitVector phiStates = leftResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector();
             storm::storage::BitVector psiStates = rightResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector();
             storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true);
@@ -680,7 +646,7 @@ namespace storm {
             if (this->getModel().getInitialStates().isSubsetOf(statesWithProbability1)) {
                 STORM_LOG_INFO("The condition holds with probability 1, so the regular reachability probability is computed.");
                 std::shared_ptr<storm::logic::BooleanLiteralFormula> trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
-                std::shared_ptr<storm::logic::UntilFormula> untilFormula = std::make_shared<storm::logic::UntilFormula>(trueFormula, pathFormula.getLeftSubformula().asSharedPointer());
+                std::shared_ptr<storm::logic::UntilFormula> untilFormula = std::make_shared<storm::logic::UntilFormula>(trueFormula, conditionalFormula.getSubformula().asSharedPointer());
                 return this->computeUntilProbabilities(*untilFormula);
             }
             
diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
index af5b464be..8b86e1dd9 100644
--- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
+++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
@@ -28,7 +28,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
 
         private:
diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp
index 1298b3fa2..983f64cae 100644
--- a/src/parser/FormulaParser.cpp
+++ b/src/parser/FormulaParser.cpp
@@ -120,8 +120,8 @@ namespace storm {
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula;
             
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> conditionalFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> eventuallyFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::ConditionalFormula::Context), Skipper> conditionalFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::EventuallyFormula::Context), Skipper> eventuallyFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula;
@@ -142,11 +142,11 @@ namespace storm {
             std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
             std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
             std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const;
-            std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const;
+            std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
-            std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const;
+            std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const;
             std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const;
             std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
@@ -253,7 +253,7 @@ namespace storm {
             cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
             cumulativeRewardFormula.name("cumulative reward formula");
             
-            rewardPathFormula = eventuallyFormula(true) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(true);
+            rewardPathFormula = eventuallyFormula(storm::logic::EventuallyFormula::Context::Reward) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(storm::logic::ConditionalFormula::Context::Reward);
             rewardPathFormula.name("reward path formula");
             
             expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)];
@@ -286,7 +286,7 @@ namespace storm {
             nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)];
             nextFormula.name("next formula");
             
-            pathFormulaWithoutUntil = eventuallyFormula(false) | globallyFormula | nextFormula | stateFormula;
+            pathFormulaWithoutUntil = eventuallyFormula(storm::logic::EventuallyFormula::Context::Probability) | globallyFormula | nextFormula | stateFormula;
             pathFormulaWithoutUntil.name("path formula");
             
             untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
@@ -298,7 +298,7 @@ namespace storm {
             timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") >  qi::uint_)[qi::_val = qi::_1];
             timeBound.name("time bound");
             
-            pathFormula = conditionalFormula(false);
+            pathFormula = conditionalFormula(storm::logic::ConditionalFormula::Context::Probability);
             pathFormula.name("path formula");
             
             operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorInformation, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
@@ -313,7 +313,7 @@ namespace storm {
             rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
             rewardOperator.name("reward operator");
             
-            expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(true) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(storm::logic::EventuallyFormula::Context::ExpectedTime) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
             expectedTimeOperator.name("expected time operator");
             
             probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
@@ -422,7 +422,7 @@ namespace storm {
             return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label));
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const {
+        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const {
             if (timeBound) {
                 if (timeBound.get().which() == 0) {
                     std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get());
@@ -431,7 +431,7 @@ namespace storm {
                     return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, static_cast<uint_fast64_t>(boost::get<uint_fast64_t>(timeBound.get()))));
                 }
             } else {
-                return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula, reward));
+                return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula, context));
             }
         }
         
@@ -456,8 +456,8 @@ namespace storm {
             }
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const {
-            return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula, reward));
+        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const {
+            return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalFormula(leftSubformula, rightSubformula, context));
         }
         
         std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> FormulaParserGrammar::createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const {
diff --git a/src/storage/bisimulation/BisimulationDecomposition.cpp b/src/storage/bisimulation/BisimulationDecomposition.cpp
index 902a69288..aedd4a998 100644
--- a/src/storage/bisimulation/BisimulationDecomposition.cpp
+++ b/src/storage/bisimulation/BisimulationDecomposition.cpp
@@ -15,6 +15,9 @@
 #include "src/settings/SettingsManager.h"
 #include "src/settings/modules/GeneralSettings.h"
 
+#include "src/logic/FormulaInformation.h"
+#include "src/logic/FragmentSpecification.h"
+
 #include "src/utility/macros.h"
 #include "src/exceptions/IllegalFunctionCallException.h"
 #include "src/exceptions/InvalidOptionException.h"
@@ -55,11 +58,14 @@ namespace storm {
             phiStates = boost::none;
             psiStates = boost::none;
             
+            // Retrieve information about formula.
+            storm::logic::FormulaInformation info = formula.info();
+            
             // Preserve rewards if necessary.
-            keepRewards = keepRewards || formula.containsRewardOperator();
+            keepRewards = keepRewards || info.containsRewardOperator();
             
             // Preserve bounded properties if necessary.
-            bounded = bounded || (formula.containsBoundedUntilFormula() || formula.containsNextFormula());
+            bounded = bounded || (info.containsBoundedUntilFormula() || info.containsNextFormula());
             
             // Compute the relevant labels and expressions.
             this->addToRespectedAtomicPropositions(formula.getAtomicExpressionFormulas(), formula.getAtomicLabelFormulas());
@@ -67,10 +73,13 @@ namespace storm {
         
         template<typename ModelType, typename BlockDataType>
         void BisimulationDecomposition<ModelType, BlockDataType>::Options::preserveSingleFormula(ModelType const& model, storm::logic::Formula const& formula) {
-            keepRewards = formula.containsRewardOperator();
+            // Retrieve information about formula.
+            storm::logic::FormulaInformation info = formula.info();
+
+            keepRewards = info.containsRewardOperator();
             
             // We need to preserve bounded properties iff the formula contains a bounded until or a next subformula.
-            bounded = formula.containsBoundedUntilFormula() || formula.containsNextFormula();
+            bounded = info.containsBoundedUntilFormula() || info.containsNextFormula();
             
             // Compute the relevant labels and expressions.
             this->addToRespectedAtomicPropositions(formula.getAtomicExpressionFormulas(), formula.getAtomicLabelFormulas());
@@ -114,12 +123,12 @@ namespace storm {
             if (newFormula->isUntilFormula()) {
                 leftSubformula = newFormula->asUntilFormula().getLeftSubformula().asSharedPointer();
                 rightSubformula = newFormula->asUntilFormula().getRightSubformula().asSharedPointer();
-                if (leftSubformula->isPropositionalFormula() && rightSubformula->isPropositionalFormula()) {
+                if (leftSubformula->isInFragment(storm::logic::propositional()) && rightSubformula->isInFragment(storm::logic::propositional())) {
                     measureDrivenInitialPartition = true;
                 }
             } else if (newFormula->isEventuallyFormula()) {
                 rightSubformula = newFormula->asEventuallyFormula().getSubformula().asSharedPointer();
-                if (rightSubformula->isPropositionalFormula()) {
+                if (rightSubformula->isInFragment(storm::logic::propositional())) {
                     measureDrivenInitialPartition = true;
                 }
             }
diff --git a/test/functional/logic/FragmentCheckerTest.cpp b/test/functional/logic/FragmentCheckerTest.cpp
new file mode 100644
index 000000000..6f21467af
--- /dev/null
+++ b/test/functional/logic/FragmentCheckerTest.cpp
@@ -0,0 +1,14 @@
+#include "gtest/gtest.h"
+#include "storm-config.h"
+#include "src/parser/FormulaParser.h"
+#include "src/logic/FragmentSpecification.h"
+#include "src/exceptions/WrongFormatException.h"
+
+TEST(FragmentCheckerTest, PctlTest) {
+    storm::parser::FormulaParser formulaParser;
+    
+    std::string input = "\"label\"";
+    std::shared_ptr<const storm::logic::Formula> formula(nullptr);
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input));
+    
+}
diff --git a/test/functional/parser/FormulaParserTest.cpp b/test/functional/parser/FormulaParserTest.cpp
index 15f116125..a3d78632b 100644
--- a/test/functional/parser/FormulaParserTest.cpp
+++ b/test/functional/parser/FormulaParserTest.cpp
@@ -1,6 +1,7 @@
 #include "gtest/gtest.h"
 #include "storm-config.h"
 #include "src/parser/FormulaParser.h"
+#include "src/logic/FragmentSpecification.h"
 #include "src/exceptions/WrongFormatException.h"
 
 TEST(FormulaParserTest, LabelTest) {
@@ -20,7 +21,7 @@ TEST(FormulaParserTest, ComplexLabelTest) {
     std::shared_ptr<const storm::logic::Formula> formula(nullptr);
 	ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input));
 
-    EXPECT_TRUE(formula->isPropositionalFormula());
+    EXPECT_TRUE(formula->isInFragment(storm::logic::propositional()));
     EXPECT_TRUE(formula->isBinaryBooleanStateFormula());
 }
 
@@ -35,7 +36,7 @@ TEST(FormulaParserTest, ExpressionTest) {
     std::shared_ptr<const storm::logic::Formula> formula(nullptr);
     ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input));
     
-    EXPECT_TRUE(formula->isPropositionalFormula());
+    EXPECT_TRUE(formula->isInFragment(storm::logic::propositional()));
     EXPECT_TRUE(formula->isUnaryBooleanStateFormula());
 }
 
@@ -50,11 +51,11 @@ TEST(FormulaParserTest, LabelAndExpressionTest) {
     std::shared_ptr<const storm::logic::Formula> formula(nullptr);
     ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input));
     
-    EXPECT_TRUE(formula->isPropositionalFormula());
+    EXPECT_TRUE(formula->isInFragment(storm::logic::propositional()));
     
     input = "x | y > 3 | !\"a\"";
     ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input));
-    EXPECT_TRUE(formula->isPropositionalFormula());
+    EXPECT_TRUE(formula->isInFragment(storm::logic::propositional()));
 }
 
 TEST(FormulaParserTest, ProbabilityOperatorTest) {
@@ -98,7 +99,7 @@ TEST(FormulaParserTest, ConditionalProbabilityTest) {
     
     EXPECT_TRUE(formula->isProbabilityOperatorFormula());
     storm::logic::ProbabilityOperatorFormula const& probFormula = formula->asProbabilityOperatorFormula();
-    EXPECT_TRUE(probFormula.getSubformula().isConditionalPathFormula());
+    EXPECT_TRUE(probFormula.getSubformula().isConditionalProbabilityFormula());
 }
 
 TEST(FormulaParserTest, NestedPathFormulaTest) {

From 7b643fe16675791ac9dade7f1f8f6f4de8678cc9 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 18 Feb 2016 23:15:35 +0100
Subject: [PATCH 05/23] tests working again

Former-commit-id: 58e97ea35b1062d75258347875558a44574ac829
---
 src/logic/FormulaInformation.cpp              |  2 +-
 src/logic/FormulaInformation.h                |  5 +++
 src/logic/FragmentChecker.cpp                 | 12 +++----
 src/logic/FragmentSpecification.cpp           |  4 ++-
 src/modelchecker/AbstractModelChecker.cpp     | 34 ++++++++++---------
 src/modelchecker/AbstractModelChecker.h       |  2 +-
 .../bisimulation/BisimulationDecomposition.h  |  8 +----
 7 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/src/logic/FormulaInformation.cpp b/src/logic/FormulaInformation.cpp
index b49f4a23b..3cbca1323 100644
--- a/src/logic/FormulaInformation.cpp
+++ b/src/logic/FormulaInformation.cpp
@@ -17,7 +17,7 @@ namespace storm {
         }
         
         bool FormulaInformation::containsBoundedUntilFormula() const {
-            return this-mContainsBoundedUntilFormula;
+            return this->mContainsBoundedUntilFormula;
         }
         
         FormulaInformation FormulaInformation::join(FormulaInformation const& other) {
diff --git a/src/logic/FormulaInformation.h b/src/logic/FormulaInformation.h
index 53269696c..6dfc90b8e 100644
--- a/src/logic/FormulaInformation.h
+++ b/src/logic/FormulaInformation.h
@@ -7,6 +7,11 @@ namespace storm {
         class FormulaInformation {
         public:
             FormulaInformation();
+            FormulaInformation(FormulaInformation const& other) = default;
+            FormulaInformation(FormulaInformation&& other) = default;
+            FormulaInformation& operator=(FormulaInformation const& other) = default;
+            FormulaInformation& operator=(FormulaInformation&& other) = default;
+            
             bool containsRewardOperator() const;
             bool containsNextFormula() const;
             bool containsBoundedUntilFormula() const;
diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp
index 405b75a27..8e701cedd 100644
--- a/src/logic/FragmentChecker.cpp
+++ b/src/logic/FragmentChecker.cpp
@@ -99,7 +99,7 @@ namespace storm {
                 result = result && inherited.getSpecification().areReachbilityExpectedTimeFormulasAllowed();
                 result = result && f.getSubformula().isStateFormula();
             }
-            result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
+            result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             return result;
         }
         
@@ -108,7 +108,7 @@ namespace storm {
             bool result = inherited.getSpecification().areExpectedTimeOperatorsAllowed();
             result = result && f.getSubformula().isExpectedTimePathFormula();
             if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
-                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
             } else {
                 result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             }
@@ -135,7 +135,7 @@ namespace storm {
             bool result = inherited.getSpecification().areLongRunAverageOperatorsAllowed();
             result = result && f.getSubformula().isStateFormula();
             if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
-                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
             } else {
                 result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             }
@@ -160,9 +160,9 @@ namespace storm {
         boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
             InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
             bool result = inherited.getSpecification().areProbabilityOperatorsAllowed();
-            result = result && f.getSubformula().isProbabilityPathFormula();
+            result = result && (f.getSubformula().isProbabilityPathFormula() || f.getSubformula().isConditionalProbabilityFormula());
             if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
-                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
             } else {
                 result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             }
@@ -174,7 +174,7 @@ namespace storm {
             bool result = inherited.getSpecification().areRewardOperatorsAllowed();
             result = result && f.getSubformula().isRewardPathFormula();
             if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
-                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false)));
+                result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
             } else {
                 result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             }
diff --git a/src/logic/FragmentSpecification.cpp b/src/logic/FragmentSpecification.cpp
index d8c02a18e..378fe3a88 100644
--- a/src/logic/FragmentSpecification.cpp
+++ b/src/logic/FragmentSpecification.cpp
@@ -1,5 +1,7 @@
 #include "src/logic/FragmentSpecification.h"
 
+#include <iostream>
+
 namespace storm {
     namespace logic {
         
@@ -50,7 +52,7 @@ namespace storm {
         }
         
         FragmentSpecification csrl() {
-            FragmentSpecification csrl;
+            FragmentSpecification csrl = csl();
             
             csrl.setRewardOperatorsAllowed(true);
             csrl.setCumulativeRewardFormulasAllowed(true);
diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index e7fabdec1..8f7a7b2f5 100644
--- a/src/modelchecker/AbstractModelChecker.cpp
+++ b/src/modelchecker/AbstractModelChecker.cpp
@@ -18,7 +18,7 @@ namespace storm {
                 return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula()));
             } else if (formula.isPathFormula()) {
                 if (formula.isProbabilityPathFormula()) {
-                    return this->computeProbabilities(checkTask.substituteFormula(formula.asPathFormula()));
+                    return this->computeProbabilities(checkTask);
                 } else if (formula.isRewardPathFormula()) {
                     return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula()));
                 }
@@ -30,20 +30,22 @@ namespace storm {
             STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid.");
         }
         
-        std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask) {
-            storm::logic::PathFormula const& pathFormula = checkTask.getFormula();
-            if (pathFormula.isBoundedUntilFormula()) {
-                return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(pathFormula.asBoundedUntilFormula()));
-            } else if (pathFormula.isEventuallyFormula()) {
-                return this->computeEventuallyProbabilities(checkTask.substituteFormula(pathFormula.asEventuallyFormula()));
-            } else if (pathFormula.isGloballyFormula()) {
-                return this->computeGloballyProbabilities(checkTask.substituteFormula(pathFormula.asGloballyFormula()));
-            } else if (pathFormula.isUntilFormula()) {
-                return this->computeUntilProbabilities(checkTask.substituteFormula(pathFormula.asUntilFormula()));
-            } else if (pathFormula.isNextFormula()) {
-                return this->computeNextProbabilities(checkTask.substituteFormula(pathFormula.asNextFormula()));
+        std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::Formula> const& checkTask) {
+            storm::logic::Formula const& formula = checkTask.getFormula();
+            if (formula.isBoundedUntilFormula()) {
+                return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(formula.asBoundedUntilFormula()));
+            } else if (formula.isEventuallyFormula()) {
+                return this->computeEventuallyProbabilities(checkTask.substituteFormula(formula.asEventuallyFormula()));
+            } else if (formula.isGloballyFormula()) {
+                return this->computeGloballyProbabilities(checkTask.substituteFormula(formula.asGloballyFormula()));
+            } else if (formula.isUntilFormula()) {
+                return this->computeUntilProbabilities(checkTask.substituteFormula(formula.asUntilFormula()));
+            } else if (formula.isNextFormula()) {
+                return this->computeNextProbabilities(checkTask.substituteFormula(formula.asNextFormula()));
+            } else if (formula.isConditionalProbabilityFormula()) {
+                return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula()));
             }
-            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << pathFormula << "' is invalid.");
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid.");
         }
         
         std::unique_ptr<CheckResult> AbstractModelChecker::computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) {
@@ -78,7 +80,7 @@ namespace storm {
                 return this->computeCumulativeRewards(checkTask.substituteFormula(rewardPathFormula.asCumulativeRewardFormula()));
             } else if (rewardPathFormula.isInstantaneousRewardFormula()) {
                 return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardPathFormula.asInstantaneousRewardFormula()));
-            } else if (rewardPathFormula.isEventuallyFormula()) {
+            } else if (rewardPathFormula.isReachabilityRewardFormula()) {
                 return this->computeReachabilityRewards(checkTask.substituteFormula(rewardPathFormula.asEventuallyFormula()));
             } else if (rewardPathFormula.isLongRunAverageRewardFormula()) {
                 return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardPathFormula.asLongRunAverageRewardFormula()));
@@ -177,7 +179,7 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) {
             storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula()));
+            std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula()));
             
             if (stateFormula.hasBound()) {
                 STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h
index c79302808..fc7fe2fdd 100644
--- a/src/modelchecker/AbstractModelChecker.h
+++ b/src/modelchecker/AbstractModelChecker.h
@@ -35,7 +35,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> check(CheckTask<storm::logic::Formula> const& checkTask);
                         
             // The methods to compute probabilities for path formulas.
-            virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask);
+            virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::Formula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask);
diff --git a/src/storage/bisimulation/BisimulationDecomposition.h b/src/storage/bisimulation/BisimulationDecomposition.h
index 420d528c9..dc1c73261 100644
--- a/src/storage/bisimulation/BisimulationDecomposition.h
+++ b/src/storage/bisimulation/BisimulationDecomposition.h
@@ -139,10 +139,7 @@ namespace storm {
             private:
                 
                 boost::optional<OptimizationDirection> optimalityType;
-                
-                
-                
-                
+
                 /// A flag that indicates whether or not the state-rewards of the model are to be respected (and should
                 /// be kept in the quotient model, if one is built).
                 bool keepRewards;
@@ -154,9 +151,6 @@ namespace storm {
                 /// when computing strong bisimulation equivalence.
                 bool bounded;
                 
-                
-                
-                
                 /*!
                  * Sets the options under the assumption that the given formula is the only one that is to be checked.
                  *

From e40cc6511778cb5478de35bdcc17df6a0149f560 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Feb 2016 11:08:41 +0100
Subject: [PATCH 06/23] added tests for fragment checker

Former-commit-id: 2de76ee5a5e149f52f0c0956addfb4597abea2e0
---
 src/parser/FormulaParser.cpp                  |   3 +-
 test/functional/logic/FragmentCheckerTest.cpp | 128 +++++++++++++++++-
 2 files changed, 124 insertions(+), 7 deletions(-)

diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp
index 983f64cae..ae7d8e0f7 100644
--- a/src/parser/FormulaParser.cpp
+++ b/src/parser/FormulaParser.cpp
@@ -351,10 +351,9 @@ namespace storm {
             debug(labelFormula);
             debug(expressionFormula);
             debug(rewardPathFormula);
-            debug(reachabilityRewardFormula);
             debug(cumulativeRewardFormula);
             debug(instantaneousRewardFormula);
-             */
+            */
 
             // Enable error reporting.
             qi::on_error<qi::fail>(start, handler(qi::_1, qi::_2, qi::_3, qi::_4));
diff --git a/test/functional/logic/FragmentCheckerTest.cpp b/test/functional/logic/FragmentCheckerTest.cpp
index 6f21467af..bb5d358c9 100644
--- a/test/functional/logic/FragmentCheckerTest.cpp
+++ b/test/functional/logic/FragmentCheckerTest.cpp
@@ -1,14 +1,132 @@
 #include "gtest/gtest.h"
 #include "storm-config.h"
 #include "src/parser/FormulaParser.h"
-#include "src/logic/FragmentSpecification.h"
+#include "src/logic/FragmentChecker.h"
 #include "src/exceptions/WrongFormatException.h"
 
-TEST(FragmentCheckerTest, PctlTest) {
+TEST(FragmentCheckerTest, Propositional) {
+    storm::logic::FragmentChecker checker;
+    storm::logic::FragmentSpecification prop = storm::logic::propositional();
+
+    storm::parser::FormulaParser formulaParser;
+    std::shared_ptr<const storm::logic::Formula> formula;
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\""));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prop));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("true"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prop));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("true | \"label\""));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prop));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("!true"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prop));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("true"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prop));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F true]"));
+    EXPECT_FALSE(checker.conformsToSpecification(*formula, prop));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("false | P>0.5 [G \"label\"]"));
+    EXPECT_FALSE(checker.conformsToSpecification(*formula, prop));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]"));
+    EXPECT_FALSE(checker.conformsToSpecification(*formula, prop));
+}
+
+TEST(FragmentCheckerTest, Pctl) {
+    storm::logic::FragmentChecker checker;
+    storm::logic::FragmentSpecification pctl = storm::logic::pctl();
+    
+    storm::parser::FormulaParser formulaParser;
+    std::shared_ptr<const storm::logic::Formula> formula;
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\""));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, pctl));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, pctl));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, pctl));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]"));
+    EXPECT_FALSE(checker.conformsToSpecification(*formula, pctl));
+}
+
+TEST(FragmentCheckerTest, Prctl) {
+    storm::logic::FragmentChecker checker;
+    storm::logic::FragmentSpecification prctl = storm::logic::prctl();
+    
+    storm::parser::FormulaParser formulaParser;
+    std::shared_ptr<const storm::logic::Formula> formula;
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\""));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [C<=3]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F[0,1] \"label\"]"));
+    EXPECT_FALSE(checker.conformsToSpecification(*formula, prctl));
+}
+
+TEST(FragmentCheckerTest, Csl) {
+    storm::logic::FragmentChecker checker;
+    storm::logic::FragmentSpecification csl = storm::logic::csl();
+    
+    storm::parser::FormulaParser formulaParser;
+    std::shared_ptr<const storm::logic::Formula> formula;
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\""));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]"));
+    EXPECT_FALSE(checker.conformsToSpecification(*formula, csl));
+
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F[0,1] \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csl));
+}
+
+TEST(FragmentCheckerTest, Csrl) {
+    storm::logic::FragmentChecker checker;
+    storm::logic::FragmentSpecification csrl = storm::logic::csrl();
+    
     storm::parser::FormulaParser formulaParser;
+    std::shared_ptr<const storm::logic::Formula> formula;
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\""));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl));
+    
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl));
     
-    std::string input = "\"label\"";
-    std::shared_ptr<const storm::logic::Formula> formula(nullptr);
-    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input));
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [C<=3]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl));
     
+    ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F[0,1] \"label\"]"));
+    EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl));
 }

From b46ee5425eadb46ca170371f4b2042ce7761bf20 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Feb 2016 17:00:41 +0100
Subject: [PATCH 07/23] started to implement conditional rewards for dtmcs

Former-commit-id: 0400ea21ef9c3f1854895b9602a7a91854276d95
---
 src/logic/ConditionalFormula.cpp              |  29 ++++-
 src/logic/ConditionalFormula.h                |   9 +-
 src/logic/EventuallyFormula.cpp               |  16 ++-
 src/logic/EventuallyFormula.h                 |   9 +-
 src/logic/Formula.cpp                         |  10 +-
 src/logic/Formula.h                           |   5 +-
 src/logic/FormulaContext.h                    |  12 ++
 src/logic/FragmentChecker.cpp                 |  10 +-
 src/modelchecker/AbstractModelChecker.cpp     |  28 ++--
 src/modelchecker/AbstractModelChecker.h       |   2 +-
 .../prctl/SparseDtmcPrctlModelChecker.cpp     |  17 ++-
 .../prctl/SparseDtmcPrctlModelChecker.h       |   6 +-
 .../prctl/helper/SparseDtmcPrctlHelper.cpp    | 120 ++++++++++++++----
 .../prctl/helper/SparseDtmcPrctlHelper.h      |  12 ++
 src/parser/FormulaParser.cpp                  |  46 +++----
 15 files changed, 238 insertions(+), 93 deletions(-)
 create mode 100644 src/logic/FormulaContext.h

diff --git a/src/logic/ConditionalFormula.cpp b/src/logic/ConditionalFormula.cpp
index 2b63fd941..af3e1d95b 100644
--- a/src/logic/ConditionalFormula.cpp
+++ b/src/logic/ConditionalFormula.cpp
@@ -1,11 +1,13 @@
 #include "src/logic/ConditionalFormula.h"
-
 #include "src/logic/FormulaVisitor.h"
 
+#include "src/utility/macros.h"
+#include "src/exceptions/InvalidPropertyException.h"
+
 namespace storm {
     namespace logic {
-        ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context) : subformula(subformula), conditionFormula(conditionFormula), context(context)  {
-            // Intentionally left empty.
+        ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, FormulaContext context) : subformula(subformula), conditionFormula(conditionFormula), context(context)  {
+            STORM_LOG_THROW(context == FormulaContext::Probability || context == FormulaContext::Reward, storm::exceptions::InvalidPropertyException, "Invalid context for formula.");
         }
         
         Formula const& ConditionalFormula::getSubformula() const {
@@ -17,11 +19,11 @@ namespace storm {
         }
         
         bool ConditionalFormula::isConditionalProbabilityFormula() const {
-            return context == Context::Probability;
+            return context == FormulaContext::Probability;
         }
         
         bool ConditionalFormula::isConditionalRewardFormula() const {
-            return context == Context::Reward;
+            return context == FormulaContext::Reward;
         }
         
         boost::any ConditionalFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
@@ -29,7 +31,22 @@ namespace storm {
         }
         
         std::shared_ptr<Formula> ConditionalFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
-            return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution));
+            return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution), context);
+        }
+        
+        void ConditionalFormula::gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const {
+            this->getSubformula().gatherAtomicExpressionFormulas(atomicExpressionFormulas);
+            this->getConditionFormula().gatherAtomicExpressionFormulas(atomicExpressionFormulas);
+        }
+        
+        void ConditionalFormula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const {
+            this->getSubformula().gatherAtomicLabelFormulas(atomicLabelFormulas);
+            this->getConditionFormula().gatherAtomicLabelFormulas(atomicLabelFormulas);
+        }
+        
+        void ConditionalFormula::gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const {
+            this->getSubformula().gatherReferencedRewardModels(referencedRewardModels);
+            this->getConditionFormula().gatherReferencedRewardModels(referencedRewardModels);
         }
         
         std::ostream& ConditionalFormula::writeToStream(std::ostream& out) const {
diff --git a/src/logic/ConditionalFormula.h b/src/logic/ConditionalFormula.h
index d7b4dc7cd..fc6b61655 100644
--- a/src/logic/ConditionalFormula.h
+++ b/src/logic/ConditionalFormula.h
@@ -2,6 +2,7 @@
 #define STORM_LOGIC_CONDITIONALFORMULA_H_
 
 #include "src/logic/BinaryPathFormula.h"
+#include "src/logic/FormulaContext.h"
 
 namespace storm {
     namespace logic {
@@ -9,7 +10,7 @@ namespace storm {
         public:
             enum class Context { Probability, Reward };
             
-            ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context = Context::Probability);
+            ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, FormulaContext context = FormulaContext::Probability);
             
             virtual ~ConditionalFormula() {
                 // Intentionally left empty.
@@ -27,10 +28,14 @@ namespace storm {
             
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
             
+            virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override;
+            virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const override;
+            virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override;
+            
         private:
             std::shared_ptr<Formula const> subformula;
             std::shared_ptr<Formula const> conditionFormula;
-            Context context;
+            FormulaContext context;
         };
     }
 }
diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp
index 3d2e6fb57..71ff4ac54 100644
--- a/src/logic/EventuallyFormula.cpp
+++ b/src/logic/EventuallyFormula.cpp
@@ -1,23 +1,25 @@
 #include "src/logic/EventuallyFormula.h"
-
 #include "src/logic/FormulaVisitor.h"
 
+#include "src/utility/macros.h"
+#include "src/exceptions/InvalidPropertyException.h"
+
 namespace storm {
     namespace logic {
-        EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context) : UnaryPathFormula(subformula), context(context) {
-            // Intentionally left empty.
+        EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, FormulaContext context) : UnaryPathFormula(subformula), context(context) {
+            STORM_LOG_THROW(context == FormulaContext::Probability || context == FormulaContext::Reward || context == FormulaContext::ExpectedTime, storm::exceptions::InvalidPropertyException, "Invalid context for formula.");
         }
         
         bool EventuallyFormula::isEventuallyFormula() const {
-            return context == Context::Probability;
+            return context == FormulaContext::Probability;
         }
         
         bool EventuallyFormula::isReachabilityRewardFormula() const {
-            return context == Context::Reward;
+            return context == FormulaContext::Reward;
         }
         
         bool EventuallyFormula::isReachbilityExpectedTimeFormula() const {
-            return context == Context::ExpectedTime;
+            return context == FormulaContext::ExpectedTime;
         }
         
         bool EventuallyFormula::isProbabilityPathFormula() const {
@@ -37,7 +39,7 @@ namespace storm {
         }
         
         std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
-            return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution));
+            return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution), context);
         }
         
         std::ostream& EventuallyFormula::writeToStream(std::ostream& out) const {
diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h
index d7a81fa83..5a0070a16 100644
--- a/src/logic/EventuallyFormula.h
+++ b/src/logic/EventuallyFormula.h
@@ -2,14 +2,13 @@
 #define STORM_LOGIC_EVENTUALLYFORMULA_H_
 
 #include "src/logic/UnaryPathFormula.h"
+#include "src/logic/FormulaContext.h"
 
 namespace storm {
     namespace logic {
         class EventuallyFormula : public UnaryPathFormula {
-        public:
-            enum class Context { Probability, Reward, ExpectedTime };
-            
-            EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context = Context::Probability);
+        public:            
+            EventuallyFormula(std::shared_ptr<Formula const> const& subformula, FormulaContext context = FormulaContext::Probability);
             
             virtual ~EventuallyFormula() {
                 // Intentionally left empty.
@@ -29,7 +28,7 @@ namespace storm {
             virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
 
         private:
-            Context context;
+            FormulaContext context;
         };
     }
 }
diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp
index d682d02aa..6c7084f53 100644
--- a/src/logic/Formula.cpp
+++ b/src/logic/Formula.cpp
@@ -256,6 +256,14 @@ namespace storm {
             return dynamic_cast<EventuallyFormula const&>(*this);
         }
         
+        EventuallyFormula& Formula::asReachabilityRewardFormula() {
+            return dynamic_cast<EventuallyFormula&>(*this);
+        }
+        
+        EventuallyFormula const& Formula::asReachabilityRewardFormula() const {
+            return dynamic_cast<EventuallyFormula const&>(*this);
+        }
+        
         GloballyFormula& Formula::asGloballyFormula() {
             return dynamic_cast<GloballyFormula&>(*this);
         }
@@ -382,7 +390,7 @@ namespace storm {
             return;
         }
         
-        void Formula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicExpressionFormulas) const {
+        void Formula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const {
             return;
         }
         
diff --git a/src/logic/Formula.h b/src/logic/Formula.h
index f2e06bc0b..7d77de7b3 100644
--- a/src/logic/Formula.h
+++ b/src/logic/Formula.h
@@ -126,6 +126,9 @@ namespace storm {
             EventuallyFormula& asEventuallyFormula();
             EventuallyFormula const& asEventuallyFormula() const;
             
+            EventuallyFormula& asReachabilityRewardFormula();
+            EventuallyFormula const& asReachabilityRewardFormula() const;
+            
             GloballyFormula& asGloballyFormula();
             GloballyFormula const& asGloballyFormula() const;
             
@@ -178,7 +181,7 @@ namespace storm {
             virtual std::ostream& writeToStream(std::ostream& out) const = 0;
             
             virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const;
-            virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicExpressionFormulas) const;
+            virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const;
             virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const;
             
         private:
diff --git a/src/logic/FormulaContext.h b/src/logic/FormulaContext.h
new file mode 100644
index 000000000..41113cb8d
--- /dev/null
+++ b/src/logic/FormulaContext.h
@@ -0,0 +1,12 @@
+#ifndef STORM_LOGIC_FORMULACONTEXT_H_
+#define STORM_LOGIC_FORMULACONTEXT_H_
+
+namespace storm {
+    namespace logic {
+        
+        enum class FormulaContext { Undefined, Probability, Reward, LongRunAverage, ExpectedTime };
+        
+    }
+}
+
+#endif /* STORM_LOGIC_FORMULACONTEXT_H_ */
\ No newline at end of file
diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp
index 8e701cedd..6bf03ddb7 100644
--- a/src/logic/FragmentChecker.cpp
+++ b/src/logic/FragmentChecker.cpp
@@ -68,11 +68,15 @@ namespace storm {
             bool result = true;
             if (f.isConditionalProbabilityFormula()) {
                 result = result && inherited.getSpecification().areConditionalProbabilityFormulasAllowed();
-            } else if (f.Formula::isConditionalRewardFormula()) {
+            } else if (f.isConditionalRewardFormula()) {
                 result = result && inherited.getSpecification().areConditionalRewardFormulasFormulasAllowed();
             }
             if (inherited.getSpecification().areOnlyEventuallyFormuluasInConditionalFormulasAllowed()) {
-                result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula();
+                if (f.isConditionalProbabilityFormula()) {
+                    result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula();
+                } else if (f.isConditionalRewardFormula()) {
+                    result = result && f.getSubformula().isReachabilityRewardFormula() && f.getConditionFormula().isEventuallyFormula();
+                }
             }
             result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
             result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data));
@@ -172,7 +176,7 @@ namespace storm {
         boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const {
             InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
             bool result = inherited.getSpecification().areRewardOperatorsAllowed();
-            result = result && f.getSubformula().isRewardPathFormula();
+            result = result && (f.getSubformula().isRewardPathFormula() || f.getSubformula().isConditionalRewardFormula());
             if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
                 result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
             } else {
diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp
index 8f7a7b2f5..ebd760d2e 100644
--- a/src/modelchecker/AbstractModelChecker.cpp
+++ b/src/modelchecker/AbstractModelChecker.cpp
@@ -20,7 +20,7 @@ namespace storm {
                 if (formula.isProbabilityPathFormula()) {
                     return this->computeProbabilities(checkTask);
                 } else if (formula.isRewardPathFormula()) {
-                    return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula()));
+                    return this->computeRewards(checkTask);
                 }
             } else if (formula.isConditionalProbabilityFormula()) {
                 return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula()));
@@ -74,18 +74,20 @@ namespace storm {
             STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
         }
         
-        std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask) {
-            storm::logic::PathFormula const& rewardPathFormula = checkTask.getFormula();
-            if (rewardPathFormula.isCumulativeRewardFormula()) {
-                return this->computeCumulativeRewards(checkTask.substituteFormula(rewardPathFormula.asCumulativeRewardFormula()));
-            } else if (rewardPathFormula.isInstantaneousRewardFormula()) {
-                return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardPathFormula.asInstantaneousRewardFormula()));
-            } else if (rewardPathFormula.isReachabilityRewardFormula()) {
-                return this->computeReachabilityRewards(checkTask.substituteFormula(rewardPathFormula.asEventuallyFormula()));
-            } else if (rewardPathFormula.isLongRunAverageRewardFormula()) {
-                return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardPathFormula.asLongRunAverageRewardFormula()));
+        std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::Formula> const& checkTask) {
+            storm::logic::Formula const& rewardFormula = checkTask.getFormula();
+            if (rewardFormula.isCumulativeRewardFormula()) {
+                return this->computeCumulativeRewards(checkTask.substituteFormula(rewardFormula.asCumulativeRewardFormula()));
+            } else if (rewardFormula.isInstantaneousRewardFormula()) {
+                return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardFormula.asInstantaneousRewardFormula()));
+            } else if (rewardFormula.isReachabilityRewardFormula()) {
+                return this->computeReachabilityRewards(checkTask.substituteFormula(rewardFormula.asEventuallyFormula()));
+            } else if (rewardFormula.isLongRunAverageRewardFormula()) {
+                return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardFormula.asLongRunAverageRewardFormula()));
+            } else if (rewardFormula.isConditionalRewardFormula()) {
+                return this->computeConditionalRewards(checkTask.substituteFormula(rewardFormula.asConditionalFormula()));
             }
-            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid.");
+            STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardFormula << "' is invalid.");
         }
         
         std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
@@ -191,7 +193,7 @@ namespace storm {
         
         std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) {
             storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula();
-            std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula()));
+            std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula()));
             
             if (checkTask.isBoundSet()) {
                 STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h
index fc7fe2fdd..90562659b 100644
--- a/src/modelchecker/AbstractModelChecker.h
+++ b/src/modelchecker/AbstractModelChecker.h
@@ -44,7 +44,7 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask);
             
             // The methods to compute the rewards for path formulas.
-            virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask);
+            virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::Formula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask);
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask);
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
index df7f1ee9a..b21d509ec 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
@@ -36,7 +36,7 @@ namespace storm {
         template<typename SparseDtmcModelType>
         bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
             storm::logic::Formula const& formula = checkTask.getFormula();
-            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true));
+            return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setConditionalRewardFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true));
         }
         
         template<typename SparseDtmcModelType>
@@ -130,6 +130,21 @@ namespace storm {
             return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
         }
         
+        template<typename SparseDtmcModelType>
+        std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
+            storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
+            STORM_LOG_THROW(conditionalFormula.getSubformula().isReachabilityRewardFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
+            STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
+            
+            std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asReachabilityRewardFormula().getSubformula());
+            std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
+            ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
+            ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
+            
+            std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);
+            return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
+        }
+        
         template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>;
     }
 }
\ No newline at end of file
diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
index 264f1725d..bdfbe5509 100644
--- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
+++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
@@ -25,11 +25,13 @@ namespace storm {
             virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
+            virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
+
             virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
             virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
-            virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
-            
+            virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
+
         private:
             // An object that is used for retrieving linear equation solvers.
             std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory;
diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
index b1401cd8a..2be798889 100644
--- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
+++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
@@ -46,7 +46,7 @@ namespace storm {
                 
                 return result;
             }
-        
+            
             template<typename ValueType, typename RewardModelType>
             std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
                 // We need to identify the states which have to be taken out of the matrix, i.e.
@@ -154,7 +154,7 @@ namespace storm {
                 
                 return result;
             }
-
+            
             template<typename ValueType, typename RewardModelType>
             std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
                 return computeReachabilityRewards(transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, targetStates, qualitative, linearEquationSolverFactory);
@@ -170,7 +170,7 @@ namespace storm {
                                                   },
                                                   targetStates, qualitative, linearEquationSolverFactory);
             }
-          
+            
             template<typename ValueType, typename RewardModelType>
             std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
                                 
@@ -222,23 +222,26 @@ namespace storm {
                 
                 return result;
             }
-
+            
             template<typename ValueType, typename RewardModelType>
             std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
                 return SparseCtmcCslHelper<ValueType>::computeLongRunAverageProbabilities(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory);
             }
             
             template<typename ValueType, typename RewardModelType>
-            std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
-                std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory);
+            typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
+                
+                BaierTransformedModel result;
                 
                 // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined.
-                storm::storage::BitVector beforeStates(targetStates.size(), true);
+                std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory);
+                
+                result.beforeStates = storm::storage::BitVector(targetStates.size(), true);
                 uint_fast64_t state = 0;
                 uint_fast64_t beforeStateIndex = 0;
                 for (auto const& value : probabilitiesToReachConditionStates) {
                     if (value == storm::utility::zero<ValueType>()) {
-                        beforeStates.set(state, false);
+                        result.beforeStates.set(state, false);
                     } else {
                         probabilitiesToReachConditionStates[beforeStateIndex] = value;
                         ++beforeStateIndex;
@@ -246,35 +249,33 @@ namespace storm {
                     ++state;
                 }
                 probabilitiesToReachConditionStates.resize(beforeStateIndex);
-
-                // If there were any before states, we can compute their conditional probabilities. If not, the result
-                // is undefined for all states.
-                std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
+                
                 if (targetStates.empty()) {
-                    storm::utility::vector::setVectorValues(result, beforeStates, storm::utility::zero<ValueType>());
-                } else if (!beforeStates.empty()) {
+                    result.noTargetStates = true;
+                    return result;
+                } else if (!result.beforeStates.empty()) {
                     // If there are some states for which the conditional probability is defined and there are some
                     // states that can reach the target states without visiting condition states first, we need to
                     // do more work.
-
+                    
                     // First, compute the relevant states and some offsets.
                     storm::storage::BitVector allStates(targetStates.size(), true);
-                    std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = beforeStates.getNumberOfSetBitsBeforeIndices();
+                    std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = result.beforeStates.getNumberOfSetBitsBeforeIndices();
                     storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates);
                     statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates);
-                    uint_fast64_t normalStatesOffset = beforeStates.getNumberOfSetBits();
+                    uint_fast64_t normalStatesOffset = result.beforeStates.getNumberOfSetBits();
                     std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices();
                     
                     // All transitions going to states with probability zero, need to be redirected to a deadlock state.
                     bool addDeadlockState = false;
                     uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits();
-
+                    
                     // Now, we create the matrix of 'before' and 'normal' states.
                     storm::storage::SparseMatrixBuilder<ValueType> builder;
                     
                     // Start by creating the transitions of the 'before' states.
                     uint_fast64_t currentRow = 0;
-                    for (auto beforeState : beforeStates) {
+                    for (auto beforeState : result.beforeStates) {
                         if (conditionStates.get(beforeState)) {
                             // For condition states, we move to the 'normal' states.
                             ValueType zeroProbability = storm::utility::zero<ValueType>();
@@ -291,7 +292,7 @@ namespace storm {
                         } else {
                             // For non-condition states, we scale the probabilities going to other before states.
                             for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
-                                if (beforeStates.get(successorEntry.getColumn())) {
+                                if (result.beforeStates.get(successorEntry.getColumn())) {
                                     builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()], successorEntry.getValue() * probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] / probabilitiesToReachConditionStates[currentRow]);
                                 }
                             }
@@ -320,21 +321,84 @@ namespace storm {
                     }
                     
                     // Build the new transition matrix and the new targets.
-                    storm::storage::SparseMatrix<ValueType> newTransitionMatrix = builder.build();
-                    storm::storage::BitVector newTargetStates = targetStates % beforeStates;
-                    newTargetStates.resize(newTransitionMatrix.getRowCount());
+                    result.transitionMatrix = builder.build();
+                    storm::storage::BitVector newTargetStates = targetStates % result.beforeStates;
+                    newTargetStates.resize(result.transitionMatrix.get().getRowCount());
                     for (auto state : targetStates % statesWithProbabilityGreater0) {
                         newTargetStates.set(normalStatesOffset + state, true);
                     }
+                    result.targetStates = std::move(newTargetStates);
+
+                    // If a reward model was given, we need to compute the rewards for the transformed model.
+                    if (stateRewards) {
+                        std::vector<ValueType> newStateRewards(result.beforeStates.getNumberOfSetBits());
+                        storm::utility::vector::selectVectorValues(newStateRewards, result.beforeStates, stateRewards.get());
+                        
+                        newStateRewards.reserve(newStateRewards.size() + statesWithProbabilityGreater0.getNumberOfSetBits() + 1);
+                        for (auto state : statesWithProbabilityGreater0) {
+                            newStateRewards.push_back(stateRewards.get()[state]);
+                        }
+                        // Add a zero reward to the deadlock state.
+                        newStateRewards.push_back(storm::utility::zero<ValueType>());
+                        result.stateRewards = std::move(newStateRewards);
+                    }
                     
-                    // Finally, compute the conditional probabiltities by a reachability query.
-                    std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), newTargetStates, qualitative, linearEquationSolverFactory);
-                    storm::utility::vector::setVectorValues(result, beforeStates, conditionalProbabilities);
                 }
-
+                
                 return result;
             }
-
+            
+            template<typename ValueType, typename RewardModelType>
+            std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
+                
+                // Prepare result vector.
+                std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
+                
+                if (!conditionStates.empty()) {
+                    BaierTransformedModel transformedModel = computeBaierTransformation(transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none, linearEquationSolverFactory);
+                    
+                    if (transformedModel.noTargetStates) {
+                        storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
+                    } else {
+                        // At this point, we do not need to check whether there are 'before' states, since the condition
+                        // states were non-empty so there is at least one state with a positive probability of satisfying
+                        // the condition.
+                        
+                        // Now compute reachability probabilities in the transformed model.
+                        storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
+                        std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory);
+                        storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
+                    }
+                }
+                
+                return result;
+            }
+            
+            template<typename ValueType, typename RewardModelType>
+            std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
+                // Prepare result vector.
+                std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
+                
+                if (!conditionStates.empty()) {
+                    BaierTransformedModel transformedModel = computeBaierTransformation(transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix), linearEquationSolverFactory);
+                    
+                    if (transformedModel.noTargetStates) {
+                        storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
+                    } else {
+                        // At this point, we do not need to check whether there are 'before' states, since the condition
+                        // states were non-empty so there is at least one state with a positive probability of satisfying
+                        // the condition.
+                        
+                        // Now compute reachability probabilities in the transformed model.
+                        storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
+                        std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory);
+                        storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
+                    }
+                }
+                
+                return result;
+            }
+            
             template class SparseDtmcPrctlHelper<double>;
         }
     }
diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h
index d1414dbce..637c30cb5 100644
--- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h
+++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h
@@ -39,8 +39,20 @@ namespace storm {
                 
                 static std::vector<ValueType> computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
                 
+                static std::vector<ValueType> computeConditionalRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
+                
             private:
                 static std::vector<ValueType> computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
+                
+                struct BaierTransformedModel {
+                    storm::storage::BitVector beforeStates;
+                    boost::optional<storm::storage::SparseMatrix<ValueType>> transitionMatrix;
+                    boost::optional<storm::storage::BitVector> targetStates;
+                    boost::optional<std::vector<ValueType>> stateRewards;
+                    bool noTargetStates;
+                };
+                
+                static BaierTransformedModel computeBaierTransformation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
             };
             
         }
diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp
index ae7d8e0f7..d8fa100c8 100644
--- a/src/parser/FormulaParser.cpp
+++ b/src/parser/FormulaParser.cpp
@@ -105,8 +105,8 @@ namespace storm {
             
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simpleFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> stateFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormulaWithoutUntil;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> pathFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> pathFormulaWithoutUntil;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simplePathFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> atomicStateFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> operatorFormula;
@@ -120,11 +120,11 @@ namespace storm {
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula;
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula;
             
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::ConditionalFormula::Context), Skipper> conditionalFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::EventuallyFormula::Context), Skipper> eventuallyFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula;
-            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> conditionalFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> eventuallyFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> nextFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> globallyFormula;
+            qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> untilFormula;
             qi::rule<Iterator, boost::variant<std::pair<double, double>, uint_fast64_t>(), Skipper> timeBound;
             
             qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardPathFormula;
@@ -142,11 +142,11 @@ namespace storm {
             std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
             std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
             std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const;
-            std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const;
+            std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
-            std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const;
+            std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::FormulaContext context) const;
             std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const;
             std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
             std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
@@ -253,7 +253,7 @@ namespace storm {
             cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
             cumulativeRewardFormula.name("cumulative reward formula");
             
-            rewardPathFormula = eventuallyFormula(storm::logic::EventuallyFormula::Context::Reward) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(storm::logic::ConditionalFormula::Context::Reward);
+            rewardPathFormula = conditionalFormula(storm::logic::FormulaContext::Reward) | eventuallyFormula(storm::logic::FormulaContext::Reward) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula;
             rewardPathFormula.name("reward path formula");
             
             expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)];
@@ -277,28 +277,28 @@ namespace storm {
             notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)];
             notStateFormula.name("negation formula");
             
-            eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_r1, qi::_2)];
+            eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_r1, qi::_2)];
             eventuallyFormula.name("eventually formula");
             
-            globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)];
+            globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)];
             globallyFormula.name("globally formula");
             
-            nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)];
+            nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)];
             nextFormula.name("next formula");
             
-            pathFormulaWithoutUntil = eventuallyFormula(storm::logic::EventuallyFormula::Context::Probability) | globallyFormula | nextFormula | stateFormula;
+            pathFormulaWithoutUntil = eventuallyFormula(qi::_r1) | globallyFormula(qi::_r1) | nextFormula(qi::_r1) | stateFormula;
             pathFormulaWithoutUntil.name("path formula");
             
-            untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
+            untilFormula = pathFormulaWithoutUntil(qi::_r1)[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
             untilFormula.name("until formula");
             
-            conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_r1)];
+            conditionalFormula = untilFormula(qi::_r1)[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula(storm::logic::FormulaContext::Probability))[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_r1)];
             conditionalFormula.name("conditional formula");
             
             timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") >  qi::uint_)[qi::_val = qi::_1];
             timeBound.name("time bound");
             
-            pathFormula = conditionalFormula(storm::logic::ConditionalFormula::Context::Probability);
+            pathFormula = conditionalFormula(qi::_r1);
             pathFormula.name("path formula");
             
             operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorInformation, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
@@ -313,10 +313,10 @@ namespace storm {
             rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
             rewardOperator.name("reward operator");
             
-            expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(storm::logic::EventuallyFormula::Context::ExpectedTime) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(storm::logic::FormulaContext::ExpectedTime) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
             expectedTimeOperator.name("expected time operator");
             
-            probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
+            probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula(storm::logic::FormulaContext::Probability) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
             probabilityOperator.name("probability operator");
             
             andStateFormula = notStateFormula[qi::_val = qi::_1] >> *(qi::lit("&") >> notStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createBinaryBooleanStateFormula, phoenix::ref(*this), qi::_val, qi::_1, storm::logic::BinaryBooleanStateFormula::OperatorType::And)];
@@ -342,10 +342,10 @@ namespace storm {
             debug(longRunAverageOperator);
             debug(pathFormulaWithoutUntil);
             debug(pathFormula);
-            debug(conditionalFormula);
+//            debug(conditionalFormula);
             debug(nextFormula);
             debug(globallyFormula);
-            debug(eventuallyFormula);
+//            debug(eventuallyFormula);
             debug(atomicStateFormula);
             debug(booleanLiteralFormula);
             debug(labelFormula);
@@ -421,7 +421,7 @@ namespace storm {
             return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label));
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const {
+        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula> const& subformula) const {
             if (timeBound) {
                 if (timeBound.get().which() == 0) {
                     std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get());
@@ -455,7 +455,7 @@ namespace storm {
             }
         }
         
-        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const {
+        std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::FormulaContext context) const {
             return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalFormula(leftSubformula, rightSubformula, context));
         }
         

From 0156b1276485e7acf60a74c25cc89a070b2ab6a3 Mon Sep 17 00:00:00 2001
From: Mavo <matthias.volk@rwth-aachen.de>
Date: Fri, 19 Feb 2016 17:36:35 +0100
Subject: [PATCH 08/23] Fixed compile problem under gcc

Former-commit-id: f5d40795e99f9d40698b8787f2409f6735a1c2f8
---
 src/builder/ExplicitDFTModelBuilder.h | 4 ++--
 src/storage/BitVectorHashMap.cpp      | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/builder/ExplicitDFTModelBuilder.h b/src/builder/ExplicitDFTModelBuilder.h
index 522f2375c..a64efaddd 100644
--- a/src/builder/ExplicitDFTModelBuilder.h
+++ b/src/builder/ExplicitDFTModelBuilder.h
@@ -50,7 +50,7 @@ namespace storm {
             
             storm::storage::DFT<ValueType> const& mDft;
             std::shared_ptr<storm::storage::DFTStateGenerationInfo> mStateGenerationInfo;
-            storm::storage::BitVectorHashMap<size_t> mStates;
+            storm::storage::BitVectorHashMap<uint32_t> mStates;
             size_t newIndex = 0;
 
         public:
@@ -71,4 +71,4 @@ namespace storm {
     }
 }
 
-#endif	/* EXPLICITDFTMODELBUILDER_H */
\ No newline at end of file
+#endif	/* EXPLICITDFTMODELBUILDER_H */
diff --git a/src/storage/BitVectorHashMap.cpp b/src/storage/BitVectorHashMap.cpp
index 4d6238350..9237dfde3 100644
--- a/src/storage/BitVectorHashMap.cpp
+++ b/src/storage/BitVectorHashMap.cpp
@@ -240,6 +240,5 @@ namespace storm {
         
         template class BitVectorHashMap<uint_fast64_t>;
         template class BitVectorHashMap<uint32_t>;
-        template class BitVectorHashMap<size_t>;
     }
 }

From b3483211ff47b7f5ca7a559e274cb6c4cdfe96b4 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Feb 2016 19:41:16 +0100
Subject: [PATCH 09/23] alpha version of conditional rewards for dtmc

Former-commit-id: 1adfb3d405ffb6b2332dc5a71e4238e85dfe7ec5
---
 src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
index 2be798889..9e1b6ef14 100644
--- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
+++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
@@ -391,8 +391,8 @@ namespace storm {
                         
                         // Now compute reachability probabilities in the transformed model.
                         storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
-                        std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory);
-                        storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
+                        std::vector<ValueType> conditionalRewards = computeReachabilityRewards(newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory);
+                        storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards);
                     }
                 }
                 

From 5ce72a85cef4d643d6c380a455dcf80e1802444d Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Fri, 19 Feb 2016 20:04:11 +0100
Subject: [PATCH 10/23] added small test for conditional probability and
 conditional rewards

Former-commit-id: 891d99eea61311d88087da1dfbc825ea00ea0995
---
 .../GmmxxDtmcPrctlModelCheckerTest.cpp        | 47 +++++++++++++++++--
 .../modelchecker/test_conditional.pm          | 18 +++++++
 2 files changed, 62 insertions(+), 3 deletions(-)
 create mode 100644 test/functional/modelchecker/test_conditional.pm

diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
index 7999da353..1e131c335 100644
--- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
+++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp
@@ -13,6 +13,8 @@
 #include "src/settings/modules/NativeEquationSolverSettings.h"
 #include "src/settings/SettingMemento.h"
 #include "src/parser/AutoParser.h"
+#include "src/parser/PrismParser.h"
+#include "src/builder/ExplicitPrismModelBuilder.h"
 
 TEST(GmmxxDtmcPrctlModelCheckerTest, Die) {
     std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew");
@@ -214,7 +216,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRASingleBscc) {
 
 TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) {
     storm::storage::SparseMatrixBuilder<double> matrixBuilder;
-    std::shared_ptr<storm::models::sparse::Dtmc<double>> mdp;
+    std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc;
 
     // A parser that we use for conveniently constructing the formulas.
     storm::parser::FormulaParser formulaParser;
@@ -260,9 +262,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) {
         ap.addLabelToState("a", 13);
         ap.addLabelToState("a", 14);
 
-        mdp.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
+        dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
 
-        storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
+        storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
 
         std::shared_ptr<const storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
 
@@ -278,3 +280,42 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) {
         EXPECT_NEAR(0.3 / 3., quantitativeResult1[14], storm::settings::nativeEquationSolverSettings().getPrecision());
     }
 }
+
+TEST(GmmxxDtmcPrctlModelCheckerTest, Conditional) {
+    storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/test_conditional.pm");
+    
+    std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>().translateProgram(program);
+    ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc);
+    ASSERT_EQ(4ul, model->getNumberOfStates());
+    ASSERT_EQ(5ul, model->getNumberOfTransitions());
+
+    std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = model->as<storm::models::sparse::Dtmc<double>>();
+
+    storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>()));
+
+    // A parser that we use for conveniently constructing the formulas.
+    storm::parser::FormulaParser formulaParser;
+    std::shared_ptr<const storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\"]");
+    
+    std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
+    storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>();
+    EXPECT_NEAR(0.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision());
+
+    formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\" || F \"condition\"]");
+    
+    result = checker.check(*formula);
+    storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>();
+    EXPECT_NEAR(storm::utility::one<double>(), quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision());
+    
+    formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\"]");
+    
+    result = checker.check(*formula);
+    storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
+    EXPECT_EQ(storm::utility::infinity<double>(), quantitativeResult3[0]);
+    
+    formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\" || F \"condition\"]");
+    
+    result = checker.check(*formula);
+    storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>();
+    EXPECT_NEAR(storm::utility::one<double>(), quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision());
+}
diff --git a/test/functional/modelchecker/test_conditional.pm b/test/functional/modelchecker/test_conditional.pm
new file mode 100644
index 000000000..57b8ba44c
--- /dev/null
+++ b/test/functional/modelchecker/test_conditional.pm
@@ -0,0 +1,18 @@
+dtmc
+
+module test
+	s : [0 .. 3] init 0;
+
+	[] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2);
+	[] s=1 -> 1 : true;
+	[] s=2 -> 1 : (s'=3);
+	[] s=3 -> 1 : true;
+
+endmodule
+
+rewards
+	s=2 : 1;
+endrewards
+
+label "condition" = s=2;
+label "target" = s=3;

From 211994bff9f69ddcc86ccb5f91fa6f11458586d4 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Sun, 21 Feb 2016 21:35:09 +0100
Subject: [PATCH 11/23] removed debug output

Former-commit-id: 915be7778b54e3f9a93a792b4f184eff83a0d957
---
 src/storage/dd/cudd/InternalCuddAdd.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/storage/dd/cudd/InternalCuddAdd.cpp b/src/storage/dd/cudd/InternalCuddAdd.cpp
index e30fd71e6..0925b4f58 100644
--- a/src/storage/dd/cudd/InternalCuddAdd.cpp
+++ b/src/storage/dd/cudd/InternalCuddAdd.cpp
@@ -230,7 +230,6 @@ namespace storm {
             if (numberOfDdVariables == 0) {
                 return 0;
             }
-            std::cout << "num dd vars: " << numberOfDdVariables << std::endl;
             return static_cast<uint_fast64_t>(this->getCuddAdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
         }
         

From 08bed3657998244156ce5f7772876e9922b8c99f Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Wed, 24 Feb 2016 17:31:18 +0100
Subject: [PATCH 12/23] fixed an issue in performance tests and renamed all
 remaining LOG4CPLUS macro invocations to that of storm

Former-commit-id: 8536943978e7313a9f9834d3f790973b7868e204
---
 src/adapters/GmmxxAdapter.h                   |  4 +-
 src/counterexamples/GenerateCounterexample.h  | 28 +++----
 .../MILPMinimalLabelSetGenerator.h            | 44 +++++-----
 .../PathBasedSubsystemGenerator.h             | 42 +++++-----
 .../SMTMinimalCommandSetGenerator.h           | 84 +++++++++----------
 .../prctl/helper/SparseMdpPrctlHelper.cpp     | 14 ++--
 src/models/sparse/Dtmc.cpp                    |  6 +-
 .../AtomicPropositionLabelingParser.cpp       | 14 ++--
 src/parser/AutoParser.cpp                     |  2 +-
 .../DeterministicSparseTransitionParser.cpp   | 32 +++----
 src/parser/MappedFile.cpp                     | 14 ++--
 src/parser/MarkovAutomatonParser.cpp          |  2 +-
 .../MarkovAutomatonSparseTransitionParser.cpp | 20 ++---
 ...NondeterministicSparseTransitionParser.cpp | 28 +++----
 src/parser/SparseChoiceLabelingParser.cpp     |  2 +-
 src/parser/SparseStateRewardParser.cpp        |  8 +-
 src/solver/GmmxxLinearEquationSolver.cpp      | 12 +--
 .../GmmxxMinMaxLinearEquationSolver.cpp       |  8 +-
 src/solver/GurobiLpSolver.cpp                 |  6 +-
 .../NativeMinMaxLinearEquationSolver.cpp      |  8 +-
 .../TopologicalMinMaxLinearEquationSolver.cpp | 36 ++++----
 src/utility/ErrorHandling.h                   | 12 +--
 src/utility/cstring.cpp                       |  8 +-
 src/utility/graph.cpp                         |  6 +-
 .../GmmxxDtmcPrctModelCheckerTest.cpp         |  2 +-
 .../NativeDtmcPrctlModelCheckerTest.cpp       |  2 +-
 26 files changed, 222 insertions(+), 222 deletions(-)

diff --git a/src/adapters/GmmxxAdapter.h b/src/adapters/GmmxxAdapter.h
index 320e57021..df81b46f7 100644
--- a/src/adapters/GmmxxAdapter.h
+++ b/src/adapters/GmmxxAdapter.h
@@ -34,7 +34,7 @@ public:
 	template<class T>
 	static std::unique_ptr<gmm::csr_matrix<T>> toGmmxxSparseMatrix(storm::storage::SparseMatrix<T> const& matrix) {
 		uint_fast64_t realNonZeros = matrix.getEntryCount();
-		LOG4CPLUS_DEBUG(logger, "Converting matrix with " << realNonZeros << " non-zeros to gmm++ format.");
+		STORM_LOG_DEBUG("Converting matrix with " << realNonZeros << " non-zeros to gmm++ format.");
 
 		// Prepare the resulting matrix.
         std::unique_ptr<gmm::csr_matrix<T>> result(new gmm::csr_matrix<T>(matrix.getRowCount(), matrix.getColumnCount()));
@@ -58,7 +58,7 @@ public:
         std::swap(result->ir, columns);
         std::swap(result->pr, values);
         
-		LOG4CPLUS_DEBUG(logger, "Done converting matrix to gmm++ format.");
+		STORM_LOG_DEBUG("Done converting matrix to gmm++ format.");
 
 		return result;
 	}
diff --git a/src/counterexamples/GenerateCounterexample.h b/src/counterexamples/GenerateCounterexample.h
index b111e16a8..f3b0e7ada 100644
--- a/src/counterexamples/GenerateCounterexample.h
+++ b/src/counterexamples/GenerateCounterexample.h
@@ -24,20 +24,20 @@
  * @param parser An AutoParser to get the model from.
  */
  void generateCounterExample(std::shared_ptr<storm::models::sparse::Model<double>> model) {
-	LOG4CPLUS_INFO(logger, "Starting counterexample generation.");
-	LOG4CPLUS_INFO(logger, "Testing inputs...");
+	STORM_LOG_INFO("Starting counterexample generation.");
+	STORM_LOG_INFO("Testing inputs...");
 
 	storm::settings::SettingsManager* s  = storm::settings::SettingsManager::getInstance();
 
 	// First test output directory.
 	std::string outPath = s->getOptionByLongName("counterExample").getArgument(0).getValueAsString();
 	if(outPath.back() != '/' && outPath.back() != '\\') {
-		LOG4CPLUS_ERROR(logger, "The output path is not valid.");
+		STORM_LOG_ERROR("The output path is not valid.");
 		return;
 	}
 	std::ofstream testFile(outPath + "test.dot");
 	if(testFile.fail()) {
-		LOG4CPLUS_ERROR(logger, "The output path is not valid.");
+		STORM_LOG_ERROR("The output path is not valid.");
 		return;
 	}
 	testFile.close();
@@ -45,7 +45,7 @@
 
  	// Differentiate between model types.
 	if(model->getType() != storm::models::DTMC) {
-		LOG4CPLUS_ERROR(logger, "Counterexample generation for the selected model type is not supported.");
+		STORM_LOG_ERROR("Counterexample generation for the selected model type is not supported.");
 		return;
 	}
 
@@ -53,21 +53,21 @@
 	// Note that the ownership of the object referenced by dtmc lies at the main function.
 	// Thus, it must not be deleted.
 	storm::models::Dtmc<double> dtmc = *(model->as<storm::models::Dtmc<double>>());
-	LOG4CPLUS_INFO(logger, "Model is a DTMC.");
+	STORM_LOG_INFO("Model is a DTMC.");
 
 	// Get specified PRCTL formulas.
 	if(!s->isSet("prctl")) {
-		LOG4CPLUS_ERROR(logger, "No PRCTL formula file specified.");
+		STORM_LOG_ERROR("No PRCTL formula file specified.");
 		return;
 	}
 
 	std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString();
-	LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << ".");
+	STORM_LOG_INFO("Parsing prctl file: " << chosenPrctlFile << ".");
 	std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile);
 
 	// Test for each formula if a counterexample can be generated for it.
 	if(formulaList.size() == 0) {
-		LOG4CPLUS_ERROR(logger, "No PRCTL formula found.");
+		STORM_LOG_ERROR("No PRCTL formula found.");
 		return;
 	}
 
@@ -94,7 +94,7 @@
 
 		// First check if it is a formula type for which a counterexample can be generated.
 		if (std::dynamic_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) {
-			LOG4CPLUS_ERROR(logger, "Unexpected kind of formula. Expected a state formula.");
+			STORM_LOG_ERROR("Unexpected kind of formula. Expected a state formula.");
 			continue;
 		}
 
@@ -102,9 +102,9 @@
 
 		// Do some output
 		std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl;
-		LOG4CPLUS_INFO(logger, "Generating counterexample for formula " + std::to_string(fIndex) + ": ");
+		STORM_LOG_INFO("Generating counterexample for formula " + std::to_string(fIndex) + ": ");
 		std::cout << "\t" << formula->toString() << "\n" << std::endl;
-		LOG4CPLUS_INFO(logger, formula->toString());
+		STORM_LOG_INFO(formula->toString());
 
 		// Now check if the model does not satisfy the formula.
 		// That is if there is at least one initial state of the model that does not.
@@ -117,14 +117,14 @@
 
 		if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) {
 			std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl;
-			LOG4CPLUS_INFO(logger, "Formula is satisfied. Can not generate counterexample.");
+			STORM_LOG_INFO("Formula is satisfied. Can not generate counterexample.");
 			continue;
 		}
 
 		// Generate counterexample
 		storm::models::Dtmc<double> counterExample = storm::counterexamples::PathBasedSubsystemGenerator<double>::computeCriticalSubsystem(dtmc, stateForm);
 
-		LOG4CPLUS_INFO(logger, "Found counterexample.");
+		STORM_LOG_INFO("Found counterexample.");
 
 		// Output counterexample
 		// Do standard output
diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h
index 87f02c668..ffc398e34 100644
--- a/src/counterexamples/MILPMinimalLabelSetGenerator.h
+++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h
@@ -98,10 +98,10 @@ namespace storm {
                 result.relevantStates &= ~psiStates;
                 result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
                 result.problematicStates &= result.relevantStates;
-                LOG4CPLUS_DEBUG(logger, "Found " << phiStates.getNumberOfSetBits() << " filter states.");
-                LOG4CPLUS_DEBUG(logger, "Found " << psiStates.getNumberOfSetBits() << " target states.");
-                LOG4CPLUS_DEBUG(logger, "Found " << result.relevantStates.getNumberOfSetBits() << " relevant states.");
-                LOG4CPLUS_DEBUG(logger, "Found " << result.problematicStates.getNumberOfSetBits() << " problematic states.");
+                STORM_LOG_DEBUG("Found " << phiStates.getNumberOfSetBits() << " filter states.");
+                STORM_LOG_DEBUG("Found " << psiStates.getNumberOfSetBits() << " target states.");
+                STORM_LOG_DEBUG("Found " << result.relevantStates.getNumberOfSetBits() << " relevant states.");
+                STORM_LOG_DEBUG("Found " << result.problematicStates.getNumberOfSetBits() << " problematic states.");
                 return result;
             }
             
@@ -158,7 +158,7 @@ namespace storm {
 
                 // Finally, determine the set of labels that are known to be taken.
                 result.knownLabels = storm::utility::counterexamples::getGuaranteedLabelSet(labeledMdp, psiStates, result.allRelevantLabels);
-                LOG4CPLUS_DEBUG(logger, "Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels.");
+                STORM_LOG_DEBUG("Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels.");
 
                 return result;
             }
@@ -364,47 +364,47 @@ namespace storm {
                 std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
                 result.labelToVariableMap = std::move(labelVariableResult.first);
                 result.numberOfVariables += labelVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for labels.");
+                STORM_LOG_DEBUG("Created variables for labels.");
                 
                 // Create scheduler variables for relevant states and their actions.
                 std::pair<std::unordered_map<uint_fast64_t, std::list<storm::expressions::Variable>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
                 result.stateToChoiceVariablesMap = std::move(schedulerVariableResult.first);
                 result.numberOfVariables += schedulerVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for nondeterministic choices.");
+                STORM_LOG_DEBUG("Created variables for nondeterministic choices.");
 
                 // Create scheduler variables for nondeterministically choosing an initial state.
                 std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
                 result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first);
                 result.numberOfVariables += initialChoiceVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for the nondeterministic choice of the initial state.");
+                STORM_LOG_DEBUG("Created variables for the nondeterministic choice of the initial state.");
                 
                 // Create variables for probabilities for all relevant states.
                 std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation);
                 result.stateToProbabilityVariableMap = std::move(probabilityVariableResult.first);
                 result.numberOfVariables += probabilityVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for the reachability probabilities.");
+                STORM_LOG_DEBUG("Created variables for the reachability probabilities.");
 
                 // Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state.
                 std::pair<storm::expressions::Variable, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
                 result.virtualInitialStateVariable = virtualInitialStateVariableResult.first;
                 result.numberOfVariables += virtualInitialStateVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for the virtual initial state.");
+                STORM_LOG_DEBUG("Created variables for the virtual initial state.");
 
                 // Create variables for problematic states.
                 std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
                 result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first);
                 result.numberOfVariables += problematicStateVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for the problematic states.");
+                STORM_LOG_DEBUG("Created variables for the problematic states.");
 
                 // Create variables for problematic choices.
                 std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
                 result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first;
                 result.numberOfVariables += problematicTransitionVariableResult.second;
-                LOG4CPLUS_DEBUG(logger, "Created variables for the problematic choices.");
+                STORM_LOG_DEBUG("Created variables for the problematic choices.");
 
                 // Finally, we need to update the model to make the new variables usable.
                 solver.update();
-                LOG4CPLUS_INFO(logger, "Successfully created " << result.numberOfVariables << " MILP variables.");
+                STORM_LOG_INFO("Successfully created " << result.numberOfVariables << " MILP variables.");
                 
                 // Finally, return variable information struct.
                 return result;
@@ -816,43 +816,43 @@ namespace storm {
             static void buildConstraintSystem(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound, bool includeSchedulerCuts = false) {
                 // Assert that the reachability probability in the subsystem exceeds the given threshold.
                 uint_fast64_t numberOfConstraints = assertProbabilityGreaterThanThreshold(solver, labeledMdp, variableInformation, probabilityThreshold, strictBound);
-                LOG4CPLUS_DEBUG(logger, "Asserted that reachability probability exceeds threshold.");
+                STORM_LOG_DEBUG("Asserted that reachability probability exceeds threshold.");
 
                 // Add constraints that assert the policy takes at most one action in each state.
                 numberOfConstraints += assertValidPolicy(solver, stateInformation, variableInformation);
-                LOG4CPLUS_DEBUG(logger, "Asserted that policy is valid.");
+                STORM_LOG_DEBUG("Asserted that policy is valid.");
 
                 // Add constraints that assert the labels that belong to some taken choices are taken as well.
                 numberOfConstraints += assertChoicesImplyLabels(solver, labeledMdp, stateInformation, choiceInformation, variableInformation);
-                LOG4CPLUS_DEBUG(logger, "Asserted that labels implied by choices are taken.");
+                STORM_LOG_DEBUG("Asserted that labels implied by choices are taken.");
 
                 // Add constraints that encode that the reachability probability from states which do not pick any action
                 // is zero.
                 numberOfConstraints += assertZeroProbabilityWithoutChoice(solver, stateInformation, choiceInformation, variableInformation);
-                LOG4CPLUS_DEBUG(logger, "Asserted that reachability probability is zero if no choice is taken.");
+                STORM_LOG_DEBUG("Asserted that reachability probability is zero if no choice is taken.");
 
                 // Add constraints that encode the reachability probabilities for states.
                 numberOfConstraints += assertReachabilityProbabilities(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation);
-                LOG4CPLUS_DEBUG(logger, "Asserted constraints for reachability probabilities.");
+                STORM_LOG_DEBUG("Asserted constraints for reachability probabilities.");
 
                 // Add constraints that ensure the reachability of an unproblematic state from each problematic state.
                 numberOfConstraints += assertUnproblematicStateReachable(solver, labeledMdp, stateInformation, choiceInformation, variableInformation);
-                LOG4CPLUS_DEBUG(logger, "Asserted that unproblematic state reachable from problematic states.");
+                STORM_LOG_DEBUG("Asserted that unproblematic state reachable from problematic states.");
 
                 // Add constraints that express that certain labels are already known to be taken.
                 numberOfConstraints += assertKnownLabels(solver, labeledMdp, psiStates, choiceInformation, variableInformation);
-                LOG4CPLUS_DEBUG(logger, "Asserted known labels are taken.");
+                STORM_LOG_DEBUG("Asserted known labels are taken.");
                 
                 // If required, assert additional constraints that reduce the number of possible policies.
                 if (includeSchedulerCuts) {
                     numberOfConstraints += assertSchedulerCuts(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation);
-                    LOG4CPLUS_DEBUG(logger, "Asserted scheduler cuts.");
+                    STORM_LOG_DEBUG("Asserted scheduler cuts.");
                 }
                 
                 // Finally, we can tell the solver to incorporate the latest changes.
                 solver.update();
                 
-                LOG4CPLUS_INFO(logger, "Successfully created " << numberOfConstraints << " MILP constraints.");
+                STORM_LOG_INFO("Successfully created " << numberOfConstraints << " MILP constraints.");
             }
             
             /*!
diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h
index 465ee5608..6061e9449 100644
--- a/src/counterexamples/PathBasedSubsystemGenerator.h
+++ b/src/counterexamples/PathBasedSubsystemGenerator.h
@@ -100,7 +100,7 @@ public:
 			}
 		}
 
-		LOG4CPLUS_DEBUG(logger, "Initialized.");
+		STORM_LOG_DEBUG("Initialized.");
 
 		//Now find the shortest distances to all states
 		while(!activeSet.empty()) {
@@ -151,7 +151,7 @@ public:
 			}
 		}
 
-		LOG4CPLUS_DEBUG(logger, "Discovery done.");
+		STORM_LOG_DEBUG("Discovery done.");
 	}
 
 	/*!
@@ -215,7 +215,7 @@ public:
 			}
 		}
 
-		LOG4CPLUS_DEBUG(logger, "Initialized.");
+		STORM_LOG_DEBUG("Initialized.");
 
 		//Now find the shortest distances to all states
 		while(!activeSet.empty()) {
@@ -269,7 +269,7 @@ public:
 			}
 		}
 
-		LOG4CPLUS_DEBUG(logger, "Discovery done.");
+		STORM_LOG_DEBUG("Discovery done.");
 	}
 
 	/*!
@@ -324,7 +324,7 @@ public:
 		if(distances[bestIndex].second == (T) -1){
 			shortestPath.push_back(bestIndex);
 			probability = (T) 0;
-			LOG4CPLUS_DEBUG(logger, "Terminal state not viable!");
+			STORM_LOG_DEBUG("Terminal state not viable!");
 			return;
 		}
 
@@ -338,8 +338,8 @@ public:
 			bestIndex = distances[bestIndex].first;
 		}
 
-		LOG4CPLUS_DEBUG(logger, "Found best state: " << bestIndex);
-		LOG4CPLUS_DEBUG(logger, "Value: " << bestValue);
+		STORM_LOG_DEBUG("Found best state: " << bestIndex);
+		STORM_LOG_DEBUG("Value: " << bestValue);
 
 		shortestPath.push_back(bestIndex);
 		bestIndex = distances[bestIndex].first;
@@ -382,9 +382,9 @@ public:
 		//-------------------------------------------------------------
 
 #ifdef BENCHMARK
-		LOG4CPLUS_INFO(logger, "Formula: " << stateFormula.toString());
+		STORM_LOG_INFO("Formula: " << stateFormula.toString());
 #endif
-		LOG4CPLUS_INFO(logger, "Start finding critical subsystem.");
+		STORM_LOG_INFO("Start finding critical subsystem.");
 
 		// make model checker
 		// TODO: Implement and use generic Model Checker factory.
@@ -397,7 +397,7 @@ public:
 		std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<T>>(stateFormula);
 
 		if(boundOperator == nullptr){
-			LOG4CPLUS_ERROR(logger, "No path bound operator at formula root.");
+			STORM_LOG_ERROR("No path bound operator at formula root.");
 			return model.getSubDtmc(subSys);
 		}
 		T bound = boundOperator->getBound();
@@ -440,7 +440,7 @@ public:
 			targetStates = until->getRight()->check(modelCheck);
 		}
 		else {
-			LOG4CPLUS_ERROR(logger, "Strange path formula. Can't decipher.");
+			STORM_LOG_ERROR("Strange path formula. Can't decipher.");
 			return model.getSubDtmc(subSys);
 		}
 
@@ -476,11 +476,11 @@ public:
 		if((initStates & targetStates).getNumberOfSetBits() != 0) {
 			subSys.set(*(initStates & targetStates).begin());
 
-			LOG4CPLUS_INFO(logger, "Critical subsystem found.");
-			LOG4CPLUS_INFO(logger, "Paths needed: " << pathCount);
-			LOG4CPLUS_INFO(logger, "State count of critical subsystem: " << subSys.getNumberOfSetBits());
-			LOG4CPLUS_INFO(logger, "Prob: " << 1);
-			LOG4CPLUS_INFO(logger, "Model checks: " << mcCount);
+			STORM_LOG_INFO("Critical subsystem found.");
+			STORM_LOG_INFO("Paths needed: " << pathCount);
+			STORM_LOG_INFO("State count of critical subsystem: " << subSys.getNumberOfSetBits());
+			STORM_LOG_INFO("Prob: " << 1);
+			STORM_LOG_INFO("Model checks: " << mcCount);
 
 			return model.getSubDtmc(subSys);
 		}
@@ -555,11 +555,11 @@ public:
 			}
 		}
 
-		LOG4CPLUS_INFO(logger, "Critical subsystem found.");
-		LOG4CPLUS_INFO(logger, "Paths needed: " << pathCount);
-		LOG4CPLUS_INFO(logger, "State count of critical subsystem: " << subSys.getNumberOfSetBits());
-		LOG4CPLUS_INFO(logger, "Prob: " << subSysProb);
-		LOG4CPLUS_INFO(logger, "Model checks: " << mcCount);
+		STORM_LOG_INFO("Critical subsystem found.");
+		STORM_LOG_INFO("Paths needed: " << pathCount);
+		STORM_LOG_INFO("State count of critical subsystem: " << subSys.getNumberOfSetBits());
+		STORM_LOG_INFO("Prob: " << subSysProb);
+		STORM_LOG_INFO("Model checks: " << mcCount);
 
 		return model.getSubDtmc(subSys);
 	}
diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h
index 3f03440d3..f7a2704b5 100644
--- a/src/counterexamples/SMTMinimalCommandSetGenerator.h
+++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h
@@ -99,8 +99,8 @@ namespace storm {
                 relevancyInformation.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
                 relevancyInformation.relevantStates &= ~psiStates;
 
-                LOG4CPLUS_DEBUG(logger, "Found " << relevancyInformation.relevantStates.getNumberOfSetBits() << " relevant states.");
-                LOG4CPLUS_DEBUG(logger, relevancyInformation.relevantStates);
+                STORM_LOG_DEBUG("Found " << relevancyInformation.relevantStates.getNumberOfSetBits() << " relevant states.");
+                STORM_LOG_DEBUG(relevancyInformation.relevantStates);
 
                 // Retrieve some references for convenient access.
                 storm::storage::SparseMatrix<T> const& transitionMatrix = labeledMdp.getTransitionMatrix();
@@ -141,7 +141,7 @@ namespace storm {
                 
                 std::cout << "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels." << std::endl;
 
-                LOG4CPLUS_DEBUG(logger, "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels.");
+                STORM_LOG_DEBUG("Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels.");
                 return relevancyInformation;
             }
             
@@ -350,9 +350,9 @@ namespace storm {
                     }
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Successfully gathered data for explicit cuts.");
+                STORM_LOG_DEBUG("Successfully gathered data for explicit cuts.");
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting initial combination is taken.");
+                STORM_LOG_DEBUG("Asserting initial combination is taken.");
                 {
                     std::vector<storm::expressions::Expression> formulae;
                     
@@ -378,7 +378,7 @@ namespace storm {
                     }
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting target combination is taken.");
+                STORM_LOG_DEBUG("Asserting target combination is taken.");
                 {
                     std::vector<storm::expressions::Expression> formulae;
 
@@ -414,7 +414,7 @@ namespace storm {
                     }
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting taken labels are followed by another label if they are not a target label.");
+                STORM_LOG_DEBUG("Asserting taken labels are followed by another label if they are not a target label.");
                 // Now assert that for each non-target label, we take a following label.
                 for (auto const& labelSetFollowingSetsPair : followingLabels) {
                     std::vector<storm::expressions::Expression> formulae;
@@ -502,7 +502,7 @@ namespace storm {
                     }
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting synchronization cuts.");
+                STORM_LOG_DEBUG("Asserting synchronization cuts.");
                 // Finally, assert that if we take one of the synchronizing labels, we also take one of the combinations
                 // the label appears in.
                 for (auto const& labelSynchronizingSetsPair : synchronizingLabels) {
@@ -667,7 +667,7 @@ namespace storm {
 
                     // If the solver reports unsat, then we know that the current selection is not enabled in the initial state.
                     if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) {
-                        LOG4CPLUS_DEBUG(logger, "Selection not enabled in initial state.");
+                        STORM_LOG_DEBUG("Selection not enabled in initial state.");
                         storm::expressions::Expression guardConjunction;
                         if (currentCommandVector.size() == 1) {
                             guardConjunction = currentCommandVector.begin()->get().getGuardExpression();
@@ -685,10 +685,10 @@ namespace storm {
                             }
                         } else {
                             throw storm::exceptions::InvalidStateException() << "Choice label set is empty.";
-                            LOG4CPLUS_DEBUG(logger, "Choice label set is empty.");
+                            STORM_LOG_DEBUG("Choice label set is empty.");
                         }
                         
-                        LOG4CPLUS_DEBUG(logger, "About to assert disjunction of negated guards.");
+                        STORM_LOG_DEBUG("About to assert disjunction of negated guards.");
                         storm::expressions::Expression guardExpression = localManager.boolean(false);
                         bool firstAssignment = true;
                         for (auto const& command : currentCommandVector) {
@@ -699,7 +699,7 @@ namespace storm {
                             }
                         }
                         localSolver->add(guardExpression);
-                        LOG4CPLUS_DEBUG(logger, "Asserted disjunction of negated guards.");
+                        STORM_LOG_DEBUG("Asserted disjunction of negated guards.");
                         
                         // Now check the possible preceding label sets for the essential ones.
                         for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) {
@@ -742,10 +742,10 @@ namespace storm {
                                     }
                                 }
                                 
-                                LOG4CPLUS_DEBUG(logger, "About to assert a weakest precondition.");
+                                STORM_LOG_DEBUG("About to assert a weakest precondition.");
                                 storm::expressions::Expression wp = guardConjunction.substitute(currentUpdateCombinationMap);
                                 formulae.push_back(wp);
-                                LOG4CPLUS_DEBUG(logger, "Asserted weakest precondition.");
+                                STORM_LOG_DEBUG("Asserted weakest precondition.");
                                 
                                 // Now try to move iterators to the next position if possible. If we could properly move it, we can directly
                                 // move on to the next combination of updates. If we have to reset it to the start, we
@@ -768,7 +768,7 @@ namespace storm {
                             // Now assert the disjunction of all weakest preconditions of all considered update combinations.
                             assertDisjunction(*localSolver, formulae, localManager);
                             
-                            LOG4CPLUS_DEBUG(logger, "Asserted disjunction of all weakest preconditions.");
+                            STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions.");
                             
                             if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) {
                                 backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet);
@@ -793,7 +793,7 @@ namespace storm {
                     }
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting taken labels are preceded by another label if they are not an initial label.");
+                STORM_LOG_DEBUG("Asserting taken labels are preceded by another label if they are not an initial label.");
                 // Now assert that for each non-target label, we take a following label.
                 for (auto const& labelSetImplicationsPair : backwardImplications) {
                     std::vector<storm::expressions::Expression> formulae;
@@ -1042,7 +1042,7 @@ namespace storm {
             static std::vector<storm::expressions::Expression> createAdder(VariableInformation const& variableInformation, std::vector<storm::expressions::Expression> const& in1, std::vector<storm::expressions::Expression> const& in2) {
                 // Sanity check for sizes of input.
                 if (in1.size() != in2.size() || in1.size() == 0) {
-                    LOG4CPLUS_ERROR(logger, "Illegal input to adder (" << in1.size() << ", " << in2.size() << ").");
+                    STORM_LOG_ERROR("Illegal input to adder (" << in1.size() << ", " << in2.size() << ").");
                     throw storm::exceptions::InvalidArgumentException() << "Illegal input to adder.";
                 }
                 
@@ -1097,7 +1097,7 @@ namespace storm {
              * @return A bit vector representing the number of literals that are set to true.
              */
             static std::vector<storm::expressions::Expression> createCounterCircuit(VariableInformation const& variableInformation, std::vector<storm::expressions::Variable> const& literals) {
-                LOG4CPLUS_DEBUG(logger, "Creating counter circuit for " << literals.size() << " literals.");
+                STORM_LOG_DEBUG("Creating counter circuit for " << literals.size() << " literals.");
 
                 // Create the auxiliary vector.
                 std::vector<std::vector<storm::expressions::Expression>> aux;
@@ -1136,7 +1136,7 @@ namespace storm {
              * @return The relaxation variable associated with the constraint.
              */
             static storm::expressions::Variable assertLessOrEqualKRelaxed(storm::solver::SmtSolver& solver, VariableInformation const& variableInformation, uint64_t k) {
-                LOG4CPLUS_DEBUG(logger, "Asserting solution has size less or equal " << k << ".");
+                STORM_LOG_DEBUG("Asserting solution has size less or equal " << k << ".");
                 
                 std::vector<storm::expressions::Variable> const& input = variableInformation.adderVariables;
                 
@@ -1209,16 +1209,16 @@ namespace storm {
                 }
                                 
                 // Check whether the assumptions are satisfiable.
-                LOG4CPLUS_DEBUG(logger, "Invoking satisfiability checking.");
+                STORM_LOG_DEBUG("Invoking satisfiability checking.");
                 z3::check_result result = solver.check(assumptions);
-                LOG4CPLUS_DEBUG(logger, "Done invoking satisfiability checking.");
+                STORM_LOG_DEBUG("Done invoking satisfiability checking.");
                 
                 if (result == z3::sat) {
                     return true;
                 } else {
-                    LOG4CPLUS_DEBUG(logger, "Computing unsat core.");
+                    STORM_LOG_DEBUG("Computing unsat core.");
                     z3::expr_vector unsatCore = solver.unsat_core();
-                    LOG4CPLUS_DEBUG(logger, "Computed unsat core.");
+                    STORM_LOG_DEBUG("Computed unsat core.");
                     
                     std::vector<z3::expr> blockingVariables;
                     blockingVariables.reserve(unsatCore.size());
@@ -1334,7 +1334,7 @@ namespace storm {
                 // As long as the constraints are unsatisfiable, we need to relax the last at-most-k constraint and
                 // try with an increased bound.
                 while (solver.checkWithAssumptions({assumption}) == storm::solver::SmtSolver::CheckResult::Unsat) {
-                    LOG4CPLUS_DEBUG(logger, "Constraint system is unsatisfiable with at most " << currentBound << " taken commands; increasing bound.");
+                    STORM_LOG_DEBUG("Constraint system is unsatisfiable with at most " << currentBound << " taken commands; increasing bound.");
                     solver.add(variableInformation.auxiliaryVariables.back());
                     variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(solver, variableInformation, ++currentBound));
                     assumption = !variableInformation.auxiliaryVariables.back();
@@ -1359,7 +1359,7 @@ namespace storm {
             static void analyzeZeroProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) {
                 storm::storage::BitVector reachableStates(subMdp.getNumberOfStates());
                 
-                LOG4CPLUS_DEBUG(logger, "Analyzing solution with zero probability.");
+                STORM_LOG_DEBUG("Analyzing solution with zero probability.");
                 
                 // Initialize the stack for the DFS.
                 bool targetStateIsReachable = false;
@@ -1403,10 +1403,10 @@ namespace storm {
                     }
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Successfully performed reachability analysis.");
+                STORM_LOG_DEBUG("Successfully performed reachability analysis.");
                 
                 if (targetStateIsReachable) {
-                    LOG4CPLUS_ERROR(logger, "Target must be unreachable for this analysis.");
+                    STORM_LOG_ERROR("Target must be unreachable for this analysis.");
                     throw storm::exceptions::InvalidStateException() << "Target must be unreachable for this analysis.";
                 }
                 
@@ -1417,7 +1417,7 @@ namespace storm {
                 std::set_difference(relevancyInformation.relevantLabels.begin(), relevancyInformation.relevantLabels.end(), commandSet.begin(), commandSet.end(), std::inserter(locallyRelevantLabels, locallyRelevantLabels.begin()));
                 
                 std::vector<boost::container::flat_set<uint_fast64_t>> guaranteedLabelSets = storm::utility::counterexamples::getGuaranteedLabelSets(originalMdp, statesThatCanReachTargetStates, locallyRelevantLabels);
-                LOG4CPLUS_DEBUG(logger, "Found " << reachableLabels.size() << " reachable labels and " << reachableStates.getNumberOfSetBits() << " reachable states.");
+                STORM_LOG_DEBUG("Found " << reachableLabels.size() << " reachable labels and " << reachableStates.getNumberOfSetBits() << " reachable states.");
                 
                 // Search for states on the border of the reachable state space, i.e. states that are still reachable
                 // and possess a (disabled) option to leave the reachable part of the state space.
@@ -1466,7 +1466,7 @@ namespace storm {
                     formulae.push_back(cube);
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting reachability implications.");
+                STORM_LOG_DEBUG("Asserting reachability implications.");
                 assertDisjunction(solver, formulae, *variableInformation.manager);
             }
             
@@ -1484,7 +1484,7 @@ namespace storm {
              */
             static void analyzeInsufficientProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) {
 
-                LOG4CPLUS_DEBUG(logger, "Analyzing solution with insufficient probability.");
+                STORM_LOG_DEBUG("Analyzing solution with insufficient probability.");
 
                 storm::storage::BitVector reachableStates(subMdp.getNumberOfStates());
                 
@@ -1529,7 +1529,7 @@ namespace storm {
                         }
                     }
                 }
-                LOG4CPLUS_DEBUG(logger, "Successfully determined reachable state space.");
+                STORM_LOG_DEBUG("Successfully determined reachable state space.");
                 
                 storm::storage::BitVector unreachableRelevantStates = ~reachableStates & relevancyInformation.relevantStates;
                 storm::storage::BitVector statesThatCanReachTargetStates = storm::utility::graph::performProbGreater0E(subMdp.getTransitionMatrix(), subMdp.getNondeterministicChoiceIndices(), subMdp.getBackwardTransitions(), phiStates, psiStates);
@@ -1574,7 +1574,7 @@ namespace storm {
                     formulae.push_back(cube);
                 }
                 
-                LOG4CPLUS_DEBUG(logger, "Asserting reachability implications.");
+                STORM_LOG_DEBUG("Asserting reachability implications.");
                 assertDisjunction(solver, formulae, *variableInformation.manager);
             }
 #endif
@@ -1627,7 +1627,7 @@ namespace storm {
                 double maximalReachabilityProbability = 0;
                 if (checkThresholdFeasible) {
                     storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper;
-                    LOG4CPLUS_DEBUG(logger, "Invoking model checker.");
+                    STORM_LOG_DEBUG("Invoking model checker.");
                     std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
                     for (auto state : labeledMdp.getInitialStates()) {
                         maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
@@ -1645,7 +1645,7 @@ namespace storm {
                 
                 // (4) Create the variables for the relevant commands.
                 VariableInformation variableInformation = createVariables(manager, labeledMdp, psiStates, relevancyInformation, includeReachabilityEncoding);
-                LOG4CPLUS_DEBUG(logger, "Created variables.");
+                STORM_LOG_DEBUG("Created variables.");
 
                 // (5) Now assert an adder whose result variables can later be used to constrain the nummber of label
                 // variables that were set to true. Initially, we are looking for a solution that has no label enabled
@@ -1654,14 +1654,14 @@ namespace storm {
                 variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(*solver, variableInformation, 0));
                 
                 // (6) Add constraints that cut off a lot of suboptimal solutions.
-                LOG4CPLUS_DEBUG(logger, "Asserting cuts.");
+                STORM_LOG_DEBUG("Asserting cuts.");
                 assertExplicitCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver);
-                LOG4CPLUS_DEBUG(logger, "Asserted explicit cuts.");
+                STORM_LOG_DEBUG("Asserted explicit cuts.");
                 assertSymbolicCuts(preparedProgram, labeledMdp, variableInformation, relevancyInformation, *solver);
-                LOG4CPLUS_DEBUG(logger, "Asserted symbolic cuts.");
+                STORM_LOG_DEBUG("Asserted symbolic cuts.");
                 if (includeReachabilityEncoding) {
                     assertReachabilityCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver);
-                    LOG4CPLUS_DEBUG(logger, "Asserted reachability cuts.");
+                    STORM_LOG_DEBUG("Asserted reachability cuts.");
                 }
                 
                 // As we are done with the setup at this point, stop the clock for the setup time.
@@ -1680,20 +1680,20 @@ namespace storm {
                 maximalReachabilityProbability = 0;
                 uint_fast64_t zeroProbabilityCount = 0;
                 do {
-                    LOG4CPLUS_DEBUG(logger, "Computing minimal command set.");
+                    STORM_LOG_DEBUG("Computing minimal command set.");
                     solverClock = std::chrono::high_resolution_clock::now();
                     commandSet = findSmallestCommandSet(*solver, variableInformation, currentBound);
                     totalSolverTime += std::chrono::high_resolution_clock::now() - solverClock;
-                    LOG4CPLUS_DEBUG(logger, "Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << ".");
+                    STORM_LOG_DEBUG("Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << ".");
                     
                     // Restrict the given MDP to the current set of labels and compute the reachability probability.
                     modelCheckingClock = std::chrono::high_resolution_clock::now();
                     commandSet.insert(relevancyInformation.knownLabels.begin(), relevancyInformation.knownLabels.end());
                     storm::models::sparse::Mdp<T> subMdp = labeledMdp.restrictChoiceLabels(commandSet);
                     storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper;
-                    LOG4CPLUS_DEBUG(logger, "Invoking model checker.");
+                    STORM_LOG_DEBUG("Invoking model checker.");
                     std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, subMdp.getTransitionMatrix(), subMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
-                    LOG4CPLUS_DEBUG(logger, "Computed model checking results.");
+                    STORM_LOG_DEBUG("Computed model checking results.");
                     totalModelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingClock;
 
                     // Now determine the maximal reachability probability by checking all initial states.
diff --git a/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
index adec586dd..09cac3521 100644
--- a/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
+++ b/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
@@ -87,9 +87,9 @@ namespace storm {
                 storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first);
                 storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second);
                 storm::storage::BitVector maybeStates = ~(statesWithProbability0 | statesWithProbability1);
-                LOG4CPLUS_INFO(logger, "Found " << statesWithProbability0.getNumberOfSetBits() << " 'no' states.");
-                LOG4CPLUS_INFO(logger, "Found " << statesWithProbability1.getNumberOfSetBits() << " 'yes' states.");
-                LOG4CPLUS_INFO(logger, "Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states.");
+                STORM_LOG_INFO("Found " << statesWithProbability0.getNumberOfSetBits() << " 'no' states.");
+                STORM_LOG_INFO("Found " << statesWithProbability1.getNumberOfSetBits() << " 'yes' states.");
+                STORM_LOG_INFO("Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states.");
                 
                 // Create resulting vector.
                 std::vector<ValueType> result(transitionMatrix.getRowGroupCount());
@@ -287,16 +287,16 @@ namespace storm {
                 }
                 infinityStates.complement();
                 storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates;
-                LOG4CPLUS_INFO(logger, "Found " << infinityStates.getNumberOfSetBits() << " 'infinity' states.");
-                LOG4CPLUS_INFO(logger, "Found " << targetStates.getNumberOfSetBits() << " 'target' states.");
-                LOG4CPLUS_INFO(logger, "Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states.");
+                STORM_LOG_INFO("Found " << infinityStates.getNumberOfSetBits() << " 'infinity' states.");
+                STORM_LOG_INFO("Found " << targetStates.getNumberOfSetBits() << " 'target' states.");
+                STORM_LOG_INFO("Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states.");
                 
                 // Create resulting vector.
                 std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
                 
                 // Check whether we need to compute exact rewards for some states.
                 if (qualitative) {
-                    LOG4CPLUS_INFO(logger, "The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed.");
+                    STORM_LOG_INFO("The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed.");
                     // Set the values for all maybe-states to 1 to indicate that their reward values
                     // are neither 0 nor infinity.
                     storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::one<ValueType>());
diff --git a/src/models/sparse/Dtmc.cpp b/src/models/sparse/Dtmc.cpp
index 31c222207..cbfeed391 100644
--- a/src/models/sparse/Dtmc.cpp
+++ b/src/models/sparse/Dtmc.cpp
@@ -33,7 +33,7 @@ namespace storm {
                 //
                 //		// Is there any state in the subsystem?
                 //		if(subSysStates.getNumberOfSetBits() == 0) {
-                //			LOG4CPLUS_ERROR(logger, "No states in subsystem!");
+                //			STORM_LOG_ERROR("No states in subsystem!");
                 //			return storm::models::Dtmc<ValueType>(storm::storage::SparseMatrix<ValueType>(),
                 //					  	  	  	  	  	  storm::models::sparse::StateLabeling(this->getStateLabeling(), subSysStates),
                 //					  	  	  	  	  	  boost::optional<std::vector<ValueType>>(),
@@ -43,13 +43,13 @@ namespace storm {
                 //
                 //		// Does the vector have the right size?
                 //		if(subSysStates.size() != this->getNumberOfStates()) {
-                //			LOG4CPLUS_INFO(logger, "BitVector has wrong size. Resizing it...");
+                //			STORM_LOG_INFO("BitVector has wrong size. Resizing it...");
                 //			subSysStates.resize(this->getNumberOfStates());
                 //		}
                 //
                 //		// Test if it is a proper subsystem of this Dtmc, i.e. if there is at least one state to be left out.
                 //		if(subSysStates.getNumberOfSetBits() == subSysStates.size()) {
-                //			LOG4CPLUS_INFO(logger, "All states are kept. This is no proper subsystem.");
+                //			STORM_LOG_INFO("All states are kept. This is no proper subsystem.");
                 //			return storm::models::Dtmc<ValueType>(*this);
                 //		}
                 //
diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index 8e51fb305..349bfb56b 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -29,7 +29,7 @@ namespace storm {
 
 			// Open the given file.
 			if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process.");
+				STORM_LOG_ERROR("Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process.");
 				throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process.";
 			}
 
@@ -68,9 +68,9 @@ namespace storm {
 
 			// If #DECLARATION or #END have not been found, the file format is wrong.
 			if (!(foundDecl && foundEnd)) {
-				LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File header is corrupted (#DECLARATION or #END missing - case sensitive).");
-				if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
-				if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
+				STORM_LOG_ERROR("Error while parsing " << filename << ": File header is corrupted (#DECLARATION or #END missing - case sensitive).");
+				if (!foundDecl) STORM_LOG_ERROR("\tDid not find #DECLARATION token.");
+				if (!foundEnd) STORM_LOG_ERROR("\tDid not find #END token.");
 				throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File header is corrupted (#DECLARATION or #END missing - case sensitive).";
 			}
 
@@ -99,7 +99,7 @@ namespace storm {
 				if (cnt >= sizeof(proposition)) {
 
 					// if token is longer than our buffer, the following strncpy code might get risky...
-					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found.");
+					STORM_LOG_ERROR("Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found.");
 					throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found.";
 
 				} else if (cnt > 0) {
@@ -138,7 +138,7 @@ namespace storm {
 
 				// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
 				if (state <= lastState && lastState != startIndexComparison) {
-					LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.");
+					STORM_LOG_ERROR("Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.");
 					throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.";
 				}
 
@@ -159,7 +159,7 @@ namespace storm {
 
 						// Has the label been declared in the header?
 						if(!labeling.containsLabel(proposition)) {
-							LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared.");
+							STORM_LOG_ERROR("Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared.");
 							throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared.";
 						}
 						labeling.addLabelToState(proposition, state);
diff --git a/src/parser/AutoParser.cpp b/src/parser/AutoParser.cpp
index 2ec30fb64..6f3c60c46 100644
--- a/src/parser/AutoParser.cpp
+++ b/src/parser/AutoParser.cpp
@@ -54,7 +54,7 @@ namespace storm {
                     break;
                 }
                 default:
-                    LOG4CPLUS_WARN(logger, "Unknown/Unhandled Model Type which cannot be parsed."); // Unknown
+                    STORM_LOG_WARN("Unknown/Unhandled Model Type which cannot be parsed."); // Unknown
             }
 
             return model;
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index 94b82a4c7..f18b46441 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -46,7 +46,7 @@ namespace storm {
             setlocale(LC_NUMERIC, "C");
 
             if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
                 throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
             }
 
@@ -58,11 +58,11 @@ namespace storm {
             bool insertDiagonalEntriesIfMissing = !isRewardFile;
             DeterministicSparseTransitionParser<ValueType>::FirstPassResult firstPass = DeterministicSparseTransitionParser<ValueType>::firstPass(file.getData(), insertDiagonalEntriesIfMissing);
 
-            LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
+            STORM_LOG_INFO("First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
 
             // If first pass returned zero, the file format was wrong.
             if (firstPass.numberOfNonzeroEntries == 0) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": empty or erroneous file format.");
                 throw storm::exceptions::WrongFormatException();
             }
 
@@ -78,7 +78,7 @@ namespace storm {
             if (isRewardFile) {
                 // The reward matrix should match the size of the transition matrix.
                 if (firstPass.highestStateIndex + 1 > transitionMatrix.getRowCount() || firstPass.highestStateIndex + 1 > transitionMatrix.getColumnCount()) {
-                    LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
+                    STORM_LOG_ERROR("Reward matrix has more rows or columns than transition matrix.");
                     throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
                 } else {
                     // If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
@@ -122,9 +122,9 @@ namespace storm {
                         hadDeadlocks = true;
                         if (!dontFixDeadlocks) {
                             resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::one<ValueType>());
-                            LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
+                            STORM_LOG_WARN("Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
                         } else {
-                            LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
+                            STORM_LOG_ERROR("Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
                             // Before throwing the appropriate exception we will give notice of all deadlock states.
                         }
                     }
@@ -143,9 +143,9 @@ namespace storm {
                         if (!rowHadDiagonalEntry) {
                             if (insertDiagonalEntriesIfMissing) {
                                 resultMatrix.addNextValue(lastRow, lastRow, storm::utility::zero<ValueType>());
-                                LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
+                                STORM_LOG_DEBUG("While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
                             } else {
-                                LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+                                STORM_LOG_WARN("Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
                             }
                             // No increment for lastRow.
                             rowHadDiagonalEntry = true;
@@ -154,9 +154,9 @@ namespace storm {
                             hadDeadlocks = true;
                             if (!dontFixDeadlocks) {
                                 resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::one<ValueType>());
-                                LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
+                                STORM_LOG_WARN("Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
                             } else {
-                                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
+                                STORM_LOG_ERROR("Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
                                 // Before throwing the appropriate exception we will give notice of all deadlock states.
                             }
                         }
@@ -171,9 +171,9 @@ namespace storm {
                     if (col > row && !rowHadDiagonalEntry) {
                         if (insertDiagonalEntriesIfMissing) {
                             resultMatrix.addNextValue(row, row, storm::utility::zero<ValueType>());
-                            LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
+                            STORM_LOG_DEBUG("While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
                         } else {
-                            LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
+                            STORM_LOG_WARN("Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
                         }
                         rowHadDiagonalEntry = true;
                     }
@@ -185,9 +185,9 @@ namespace storm {
                 if (!rowHadDiagonalEntry) {
                     if (insertDiagonalEntriesIfMissing) {
                         resultMatrix.addNextValue(lastRow, lastRow, storm::utility::zero<ValueType>());
-                        LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
+                        STORM_LOG_DEBUG("While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
                     } else {
-                        LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
+                        STORM_LOG_WARN("Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
                     }
                 }
 
@@ -200,7 +200,7 @@ namespace storm {
 
             // Since we cannot check if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
             if (isRewardFile && !result.isSubmatrixOf(transitionMatrix)) {
-                LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file.");
+                STORM_LOG_ERROR("There are rewards for non existent transitions given in the reward file.");
                 throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file.";
             }
 
@@ -272,7 +272,7 @@ namespace storm {
 
                 // Have we already seen this transition?
                 if (row == lastRow && col == lastCol) {
-                    LOG4CPLUS_ERROR(logger, "The same transition (" << row << ", " << col << ") is given twice.");
+                    STORM_LOG_ERROR("The same transition (" << row << ", " << col << ") is given twice.");
                     throw storm::exceptions::InvalidArgumentException() << "The same transition (" << row << ", " << col << ") is given twice.";
                 }
 
diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp
index 7abf526cf..86f2648eb 100644
--- a/src/parser/MappedFile.cpp
+++ b/src/parser/MappedFile.cpp
@@ -33,20 +33,20 @@ namespace storm {
 		#else
 			if (stat64(filename, &(this->st)) != 0) {
 		#endif
-				LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): Probably, this file does not exist.");
+				STORM_LOG_ERROR("Error in stat(" << filename << "): Probably, this file does not exist.");
 				throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist.";
 			}
 			this->file = open(filename, O_RDONLY);
 
 			if (this->file < 0) {
-				LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): Probably, we may not read this file.");
+				STORM_LOG_ERROR("Error in open(" << filename << "): Probably, we may not read this file.");
 				throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file.";
 			}
             
 			this->data = static_cast<char*>(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0));
 			if (this->data == MAP_FAILED) {
 				close(this->file);
-				LOG4CPLUS_ERROR(logger, "Error in mmap(" << filename << "): " << std::strerror(errno));
+				STORM_LOG_ERROR("Error in mmap(" << filename << "): " << std::strerror(errno));
 				throw exceptions::FileIoException() << "MappedFile Error in mmap(): " << std::strerror(errno);
 			}
 			this->dataEnd = this->data + this->st.st_size;
@@ -56,20 +56,20 @@ namespace storm {
 			// _stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile()
 
 			if (_stat64(filename, &(this->st)) != 0) {
-				LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist.");
+				STORM_LOG_ERROR("Error in _stat(" << filename << "): Probably, this file does not exist.");
 				throw exceptions::FileIoException("MappedFile Error in stat(): Probably, this file does not exist.");
 			}
 
 			this->file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 			if (this->file == INVALID_HANDLE_VALUE) {
-				LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << "): Probably, we may not read this file.");
+				STORM_LOG_ERROR("Error in CreateFileA(" << filename << "): Probably, we may not read this file.");
 				throw exceptions::FileIoException("MappedFile Error in CreateFileA(): Probably, we may not read this file.");
 			}
 
 			this->mapping = CreateFileMappingA(this->file, NULL, PAGE_READONLY, (DWORD)(st.st_size >> 32), (DWORD)st.st_size, NULL);
 			if (this->mapping == NULL) {
 				CloseHandle(this->file);
-				LOG4CPLUS_ERROR(logger, "Error in CreateFileMappingA(" << filename << ").");
+				STORM_LOG_ERROR("Error in CreateFileMappingA(" << filename << ").");
 				throw exceptions::FileIoException("MappedFile Error in CreateFileMappingA().");
 			}
 
@@ -77,7 +77,7 @@ namespace storm {
 			if (this->data == NULL) {
 				CloseHandle(this->mapping);
 				CloseHandle(this->file);
-				LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ").");
+				STORM_LOG_ERROR("Error in MapViewOfFile(" << filename << ").");
 				throw exceptions::FileIoException("MappedFile Error in MapViewOfFile().");
 			}
 			this->dataEnd = this->data + this->st.st_size;
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index 6a68abda8..b4ee7be34 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -37,7 +37,7 @@ namespace storm {
 
             // Since Markov Automata do not support transition rewards no path should be given here.
             if (transitionRewardFilename != "") {
-                LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata.");
+                STORM_LOG_ERROR("Transition rewards are unsupported for Markov automata.");
                 throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata.";
             }
 
diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
index 6bc214cab..18d87d314 100644
--- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp
+++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp
@@ -48,11 +48,11 @@ namespace storm {
                         result.numberOfNonzeroEntries += source - lastsource - 1;
                         result.numberOfChoices += source - lastsource - 1;
                     } else {
-                        LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
+                        STORM_LOG_ERROR("Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
                         throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
                     }
                 } else if (source < lastsource) {
-                    LOG4CPLUS_ERROR(logger, "Illegal state choice order. A choice of state " << source << " appears at an illegal position.");
+                    STORM_LOG_ERROR("Illegal state choice order. A choice of state " << source << " appears at an illegal position.");
                     throw storm::exceptions::WrongFormatException() << "Illegal state choice order. A choice of state " << source << " appears at an illegal position.";
                 }
 
@@ -80,11 +80,11 @@ namespace storm {
 
                 if (isMarkovianChoice) {
                     if (stateHasMarkovianChoice) {
-                        LOG4CPLUS_ERROR(logger, "The state " << source << " has multiple Markovian choices.");
+                        STORM_LOG_ERROR("The state " << source << " has multiple Markovian choices.");
                         throw storm::exceptions::WrongFormatException() << "The state " << source << " has multiple Markovian choices.";
                     }
                     if (stateHasProbabilisticChoice) {
-                        LOG4CPLUS_ERROR(logger, "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.");
+                        STORM_LOG_ERROR("The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.");
                         throw storm::exceptions::WrongFormatException() << "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed.";
                     }
                     stateHasMarkovianChoice = true;
@@ -106,7 +106,7 @@ namespace storm {
                     // If the end of the file was reached, we need to abort and check whether we are in a legal state.
                     if (buf[0] == '\0') {
                         if (!hasSuccessorState) {
-                            LOG4CPLUS_ERROR(logger, "Premature end-of-file. Expected at least one successor state for state " << source << ".");
+                            STORM_LOG_ERROR("Premature end-of-file. Expected at least one successor state for state " << source << ".");
                             throw storm::exceptions::WrongFormatException() << "Premature end-of-file. Expected at least one successor state for state " << source << ".";
                         } else {
                             // If there was at least one successor for the current choice, this is legal and we need to move on.
@@ -122,18 +122,18 @@ namespace storm {
                             result.highestStateIndex = target;
                         }
                         if (hasSuccessorState && target <= lastSuccessorState) {
-                            LOG4CPLUS_ERROR(logger, "Illegal transition order for source state " << source << ".");
+                            STORM_LOG_ERROR("Illegal transition order for source state " << source << ".");
                             throw storm::exceptions::WrongFormatException() << "Illegal transition order for source state " << source << ".";
                         }
 
                         // And the corresponding probability/rate.
                         double val = checked_strtod(buf, &buf);
                         if (val < 0.0) {
-                            LOG4CPLUS_ERROR(logger, "Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
+                            STORM_LOG_ERROR("Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << ".");
                             throw storm::exceptions::WrongFormatException() << "Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << ".";
                         }
                         if (!isMarkovianChoice && val > 1.0) {
-                            LOG4CPLUS_ERROR(logger, "Illegal probability value for transition from " << source << " to " << target << ": " << val << ".");
+                            STORM_LOG_ERROR("Illegal probability value for transition from " << source << " to " << target << ": " << val << ".");
                             throw storm::exceptions::WrongFormatException() << "Illegal probability value for transition from " << source << " to " << target << ": " << val << ".";
                         }
 
@@ -191,7 +191,7 @@ namespace storm {
                             ++currentChoice;
                         }
                     } else {
-                        LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
+                        STORM_LOG_ERROR("Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.");
                         throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag.";
                     }
                 }
@@ -269,7 +269,7 @@ namespace storm {
             setlocale(LC_NUMERIC, "C");
 
             if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
                 throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
             }
 
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 421f3b8cc..89322808c 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -44,7 +44,7 @@ namespace storm {
             setlocale(LC_NUMERIC, "C");
 
             if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
                 throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
             }
 
@@ -57,7 +57,7 @@ namespace storm {
 
             // If first pass returned zero, the file format was wrong.
             if (firstPass.numberOfNonzeroEntries == 0) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": erroneous file format.");
                 throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": erroneous file format.";
             }
 
@@ -73,13 +73,13 @@ namespace storm {
             if (isRewardFile) {
                 // The reward matrix should match the size of the transition matrix.
                 if (firstPass.choices > modelInformation.getRowCount() || (uint_fast64_t) (firstPass.highestStateIndex + 1) > modelInformation.getColumnCount()) {
-                    LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size.");
+                    STORM_LOG_ERROR("Reward matrix size exceeds transition matrix size.");
                     throw storm::exceptions::OutOfRangeException() << "Reward matrix size exceeds transition matrix size.";
                 } else if (firstPass.choices != modelInformation.getRowCount()) {
-                    LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count.");
+                    STORM_LOG_ERROR("Reward matrix row count does not match transition matrix row count.");
                     throw storm::exceptions::OutOfRangeException() << "Reward matrix row count does not match transition matrix row count.";
                 } else if (firstPass.numberOfNonzeroEntries > modelInformation.getEntryCount()) {
-                    LOG4CPLUS_ERROR(logger, "The reward matrix has more entries than the transition matrix. There must be a reward for a non existent transition");
+                    STORM_LOG_ERROR("The reward matrix has more entries than the transition matrix. There must be a reward for a non existent transition");
                     throw storm::exceptions::OutOfRangeException() << "The reward matrix has more entries than the transition matrix.";
                 } else {
                     firstPass.highestStateIndex = modelInformation.getColumnCount() - 1;
@@ -89,7 +89,7 @@ namespace storm {
             // Create the matrix builder.
             // The matrix to be build should have as many columns as we have nodes and as many rows as we have choices.
             // Those two values, as well as the number of nonzero elements, was been calculated in the first run.
-            LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << firstPass.choices << " x " << (firstPass.highestStateIndex + 1) << " with " << firstPass.numberOfNonzeroEntries << " entries.");
+            STORM_LOG_INFO("Attempting to create matrix of size " << firstPass.choices << " x " << (firstPass.highestStateIndex + 1) << " with " << firstPass.numberOfNonzeroEntries << " entries.");
             storm::storage::SparseMatrixBuilder<ValueType> matrixBuilder;
             if (!isRewardFile) {
                 matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(firstPass.choices, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries, true, true, firstPass.highestStateIndex + 1);
@@ -155,9 +155,9 @@ namespace storm {
                             matrixBuilder.newRowGroup(curRow);
                             matrixBuilder.addNextValue(curRow, node, 1);
                             ++curRow;
-                            LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted.");
+                            STORM_LOG_WARN("Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted.");
                         } else {
-                            LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": node " << node << " has no outgoing transitions.");
+                            STORM_LOG_ERROR("Error while parsing " << filename << ": node " << node << " has no outgoing transitions.");
                         }
                     }
                     if (source != lastSource) {
@@ -194,7 +194,7 @@ namespace storm {
 
             // Since we cannot check if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
             if (isRewardFile && !resultMatrix.isSubmatrixOf(modelInformation)) {
-                LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file.");
+                STORM_LOG_ERROR("There are rewards for non existent transitions given in the reward file.");
                 throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file.";
             }
 
@@ -230,7 +230,7 @@ namespace storm {
                 choice = checked_strtol(buf, &buf);
 
                 if (source < lastSource) {
-                    LOG4CPLUS_ERROR(logger, "The current source state " << source << " is smaller than the last one " << lastSource << ".");
+                    STORM_LOG_ERROR("The current source state " << source << " is smaller than the last one " << lastSource << ".");
                     throw storm::exceptions::InvalidArgumentException() << "The current source state " << source << " is smaller than the last one " << lastSource << ".";
                 }
 
@@ -243,7 +243,7 @@ namespace storm {
 
                     // Make sure that the highest state index of the reward file is not higher than the highest state index of the corresponding model.
                     if (result.highestStateIndex > modelInformation.getColumnCount() - 1) {
-                        LOG4CPLUS_ERROR(logger, "State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " .");
+                        STORM_LOG_ERROR("State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " .");
                         throw storm::exceptions::OutOfRangeException() << "State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " .";
                     }
 
@@ -292,18 +292,18 @@ namespace storm {
 
                 // Also, have we already seen this transition?
                 if (target == lastTarget && choice == lastChoice && source == lastSource) {
-                    LOG4CPLUS_ERROR(logger, "The same transition (" << source << ", " << choice << ", " << target << ") is given twice.");
+                    STORM_LOG_ERROR("The same transition (" << source << ", " << choice << ", " << target << ") is given twice.");
                     throw storm::exceptions::InvalidArgumentException() << "The same transition (" << source << ", " << choice << ", " << target << ") is given twice.";
                 }
 
                 // Read value and check whether it's positive.
                 val = checked_strtod(buf, &buf);
                 if (!isRewardFile && (val < 0.0 || val > 1.0)) {
-                    LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
+                    STORM_LOG_ERROR("Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\".");
                     NondeterministicSparseTransitionParser::FirstPassResult nullResult;
                     return nullResult;
                 } else if (val < 0.0) {
-                    LOG4CPLUS_ERROR(logger, "Expected a positive reward value but got \"" << std::string(buf, 0, 16) << "\".");
+                    STORM_LOG_ERROR("Expected a positive reward value but got \"" << std::string(buf, 0, 16) << "\".");
                     NondeterministicSparseTransitionParser::FirstPassResult nullResult;
                     return nullResult;
                 }
diff --git a/src/parser/SparseChoiceLabelingParser.cpp b/src/parser/SparseChoiceLabelingParser.cpp
index 7bfeeb459..999a98841 100644
--- a/src/parser/SparseChoiceLabelingParser.cpp
+++ b/src/parser/SparseChoiceLabelingParser.cpp
@@ -14,7 +14,7 @@ namespace storm {
         std::vector<storm::models::sparse::LabelSet> SparseChoiceLabelingParser::parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename) {
             // Open file.
             if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
                 throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
             }
 
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index b60856eb8..35e1c3d59 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -22,7 +22,7 @@ namespace storm {
         std::vector<ValueType> SparseStateRewardParser<ValueType>::parseSparseStateReward(uint_fast64_t stateCount, std::string const& filename) {
             // Open file.
             if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
-                LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
+                STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
                 throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
             }
 
@@ -47,12 +47,12 @@ namespace storm {
                 // If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
                 // Note: The value -1 shows that lastState has not yet been set, i.e. this is the first run of the loop (state index (2^64)-1 is a really bad starting index).
                 if (state <= lastState && lastState != startIndexComparison) {
-                    LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.");
+                    STORM_LOG_ERROR("Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.");
                     throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.";
                 }
 
                 if (stateCount <= state) {
-                    LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Found reward for a state of an invalid index \"" << state << "\". The model has only " << stateCount << " states.");
+                    STORM_LOG_ERROR("Error while parsing " << filename << ": Found reward for a state of an invalid index \"" << state << "\". The model has only " << stateCount << " states.");
                     throw storm::exceptions::OutOfRangeException() << "Error while parsing " << filename << ": Found reward for a state of an invalid index \"" << state << "\"";
                 }
 
@@ -60,7 +60,7 @@ namespace storm {
                 reward = checked_strtod(buf, &buf);
 
                 if (reward < 0.0) {
-                    LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Expected positive reward value but got \"" << reward << "\".");
+                    STORM_LOG_ERROR("Error while parsing " << filename << ": Expected positive reward value but got \"" << reward << "\".");
                     throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State reward file specifies illegal reward value.";
                 }
 
diff --git a/src/solver/GmmxxLinearEquationSolver.cpp b/src/solver/GmmxxLinearEquationSolver.cpp
index 3b7bbf476..eb869481c 100644
--- a/src/solver/GmmxxLinearEquationSolver.cpp
+++ b/src/solver/GmmxxLinearEquationSolver.cpp
@@ -56,9 +56,9 @@ namespace storm {
         
         template<typename ValueType>
         void GmmxxLinearEquationSolver<ValueType>::solveEquationSystem(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult) const {
-            LOG4CPLUS_INFO(logger, "Using method '" << methodToString() << "' with preconditioner '" << preconditionerToString() << "' (max. " << maximalNumberOfIterations << " iterations).");
+            STORM_LOG_INFO("Using method '" << methodToString() << "' with preconditioner '" << preconditionerToString() << "' (max. " << maximalNumberOfIterations << " iterations).");
             if (method == SolutionMethod::Jacobi && preconditioner != Preconditioner::None) {
-                LOG4CPLUS_WARN(logger, "Jacobi method currently does not support preconditioners. The requested preconditioner will be ignored.");
+                STORM_LOG_WARN("Jacobi method currently does not support preconditioners. The requested preconditioner will be ignored.");
             }
             
             if (method == SolutionMethod::Bicgstab || method == SolutionMethod::Qmr || method == SolutionMethod::Gmres) {
@@ -93,18 +93,18 @@ namespace storm {
                 
                 // Check if the solver converged and issue a warning otherwise.
                 if (iter.converged()) {
-                    LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iter.get_iteration() << " iterations.");
+                    STORM_LOG_INFO("Iterative solver converged after " << iter.get_iteration() << " iterations.");
                 } else {
-                    LOG4CPLUS_WARN(logger, "Iterative solver did not converge.");
+                    STORM_LOG_WARN("Iterative solver did not converge.");
                 }
             } else if (method == SolutionMethod::Jacobi) {
                 uint_fast64_t iterations = solveLinearEquationSystemWithJacobi(*originalA, x, b, multiplyResult);
                 
                 // Check if the solver converged and issue a warning otherwise.
                 if (iterations < maximalNumberOfIterations) {
-                    LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations.");
+                    STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations.");
                 } else {
-                    LOG4CPLUS_WARN(logger, "Iterative solver did not converge.");
+                    STORM_LOG_WARN("Iterative solver did not converge.");
                 }
             }
         }
diff --git a/src/solver/GmmxxMinMaxLinearEquationSolver.cpp b/src/solver/GmmxxMinMaxLinearEquationSolver.cpp
index 07052e6eb..eed6fb258 100644
--- a/src/solver/GmmxxMinMaxLinearEquationSolver.cpp
+++ b/src/solver/GmmxxMinMaxLinearEquationSolver.cpp
@@ -69,9 +69,9 @@ namespace storm {
 
 				// Check if the solver converged and issue a warning otherwise.
 				if (converged) {
-					LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations.");
+					STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations.");
 				} else {
-					LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations.");
+					STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations.");
 				}
 
 				// If we performed an odd number of iterations, we need to swap the x and currentX, because the newest result
@@ -149,9 +149,9 @@ namespace storm {
 
 				// Check if the solver converged and issue a warning otherwise.
 				if (converged) {
-					LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations.");
+					STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations.");
 				} else {
-					LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations.");
+					STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations.");
 				}
                 
                 // If requested, we store the scheduler for retrieval.
diff --git a/src/solver/GurobiLpSolver.cpp b/src/solver/GurobiLpSolver.cpp
index 202aa6e45..4108f2bb8 100644
--- a/src/solver/GurobiLpSolver.cpp
+++ b/src/solver/GurobiLpSolver.cpp
@@ -26,7 +26,7 @@ namespace storm {
             // Create the environment.
             int error = GRBloadenv(&env, "");
             if (error || env == nullptr) {
-				LOG4CPLUS_ERROR(logger, "Could not initialize Gurobi (" << GRBgeterrormsg(env) << ", error code " << error << ").");
+				STORM_LOG_ERROR("Could not initialize Gurobi (" << GRBgeterrormsg(env) << ", error code " << error << ").");
 				throw storm::exceptions::InvalidStateException() << "Could not initialize Gurobi environment (" << GRBgeterrormsg(env) << ", error code " << error << ").";
             }
             
@@ -36,7 +36,7 @@ namespace storm {
             // Create the model.
             error = GRBnewmodel(env, &model, name.c_str(), 0, nullptr, nullptr, nullptr, nullptr, nullptr);
             if (error) {
-				LOG4CPLUS_ERROR(logger, "Could not initialize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
+				STORM_LOG_ERROR("Could not initialize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").");
 				throw storm::exceptions::InvalidStateException() << "Could not initialize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ").";
             }
         }
@@ -346,7 +346,7 @@ namespace storm {
         void GurobiLpSolver::writeModelToFile(std::string const& filename) const {
             int error = GRBwrite(model, filename.c_str());
             if (error) {
-				LOG4CPLUS_ERROR(logger, "Unable to write Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ") to file.");
+				STORM_LOG_ERROR("Unable to write Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ") to file.");
 				throw storm::exceptions::InvalidStateException() << "Unable to write Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ") to file.";
             }
         }
diff --git a/src/solver/NativeMinMaxLinearEquationSolver.cpp b/src/solver/NativeMinMaxLinearEquationSolver.cpp
index 22ccf956c..ec369ee3e 100644
--- a/src/solver/NativeMinMaxLinearEquationSolver.cpp
+++ b/src/solver/NativeMinMaxLinearEquationSolver.cpp
@@ -65,9 +65,9 @@ namespace storm {
 
 				// Check if the solver converged and issue a warning otherwise.
 				if (converged) {
-					LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations.");
+					STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations.");
 				} else {
-					LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations.");
+					STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations.");
 				}
 
 				// If we performed an odd number of iterations, we need to swap the x and currentX, because the newest result
@@ -147,9 +147,9 @@ namespace storm {
 
 				// Check if the solver converged and issue a warning otherwise.
 				if (converged) {
-					LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations.");
+					STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations.");
 				} else {
-					LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations.");
+					STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations.");
 				}
 
                 // If requested, we store the scheduler for retrieval.
diff --git a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp
index f16c92a07..bb912371b 100644
--- a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp
+++ b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp
@@ -73,10 +73,10 @@ namespace storm {
 			// For testing only
 			if (sizeof(ValueType) == sizeof(double)) {
 				//std::cout << "<<< Using CUDA-DOUBLE Kernels >>>" << std::endl;
-				LOG4CPLUS_INFO(logger, "<<< Using CUDA-DOUBLE Kernels >>>");
+				STORM_LOG_INFO("<<< Using CUDA-DOUBLE Kernels >>>");
 			} else {
 				//std::cout << "<<< Using CUDA-FLOAT Kernels >>>" << std::endl;
-				LOG4CPLUS_INFO(logger, "<<< Using CUDA-FLOAT Kernels >>>");
+				STORM_LOG_INFO("<<< Using CUDA-FLOAT Kernels >>>");
 			}
 
 			// Now, we need to determine the SCCs of the MDP and perform a topological sort.
@@ -107,12 +107,12 @@ namespace storm {
 				} else {
 					result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(this->maximalNumberOfIterations, this->precision, this->relative, A.rowIndications, A.columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations);
 				}
-				LOG4CPLUS_INFO(logger, "Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU.");
+				STORM_LOG_INFO("Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU.");
 
 				bool converged = false;
 				if (!result) {
 					converged = false;
-					LOG4CPLUS_ERROR(logger, "An error occurred in the CUDA Plugin. Can not continue.");
+					STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue.");
 					throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue.";
 				} else {
 					converged = true;
@@ -120,12 +120,12 @@ namespace storm {
 
 				// Check if the solver converged and issue a warning otherwise.
 				if (converged) {
-					LOG4CPLUS_INFO(logger, "Iterative solver converged after " << globalIterations << " iterations.");
+					STORM_LOG_INFO("Iterative solver converged after " << globalIterations << " iterations.");
 				} else {
-					LOG4CPLUS_WARN(logger, "Iterative solver did not converged after " << globalIterations << " iterations.");
+					STORM_LOG_WARN("Iterative solver did not converged after " << globalIterations << " iterations.");
 				}
 #else
-				LOG4CPLUS_ERROR(logger, "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!");
+				STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!");
 				throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!";
 #endif
 			} else {
@@ -139,7 +139,7 @@ namespace storm {
 
 				// Calculate the optimal distribution of sccs
 				std::vector<std::pair<bool, storm::storage::StateBlock>> optimalSccs = this->getOptimalGroupingFromTopologicalSccDecomposition(sccDecomposition, topologicalSort, this->A);
-				LOG4CPLUS_INFO(logger, "Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs.");
+				STORM_LOG_INFO("Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs.");
 
 				std::vector<ValueType>* currentX = nullptr;
 				std::vector<ValueType>* swap = nullptr;
@@ -198,9 +198,9 @@ namespace storm {
 #ifdef STORM_HAVE_CUDA
                         STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA-based equation solver.");
 
-						//LOG4CPLUS_INFO(logger, "Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%).");
-						//LOG4CPLUS_INFO(logger, "We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes.");
-						//LOG4CPLUS_INFO(logger, "The CUDA Runtime Version is " << getRuntimeCudaVersion());
+						//STORM_LOG_INFO("Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%).");
+						//STORM_LOG_INFO("We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes.");
+						//STORM_LOG_INFO("The CUDA Runtime Version is " << getRuntimeCudaVersion());
 
 						bool result = false;
 						localIterations = 0;
@@ -209,11 +209,11 @@ namespace storm {
 						} else {
 							result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(this->maximalNumberOfIterations, this->precision, this->relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations);
 						}
-						LOG4CPLUS_INFO(logger, "Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU.");
+						STORM_LOG_INFO("Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU.");
 
 						if (!result) {
 							converged = false;
-							LOG4CPLUS_ERROR(logger, "An error occurred in the CUDA Plugin. Can not continue.");
+							STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue.");
 							throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue.";
 						} else {
 							converged = true;
@@ -226,12 +226,12 @@ namespace storm {
 						}
 						globalIterations += localIterations;
 #else
-						LOG4CPLUS_ERROR(logger, "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!");
+						STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!");
 						throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!";
 #endif
 					} else {
 						//std::cout << "WARNING: Using CPU based TopoSolver! (double)" << std::endl;
-						LOG4CPLUS_INFO(logger, "Performance Warning: Using CPU based TopoSolver! (double)");
+						STORM_LOG_INFO("Performance Warning: Using CPU based TopoSolver! (double)");
 						localIterations = 0;
 						converged = false;
 						while (!converged && localIterations < this->maximalNumberOfIterations) {
@@ -263,7 +263,7 @@ namespace storm {
 							++localIterations;
 							++globalIterations;
 						}
-						LOG4CPLUS_INFO(logger, "Executed " << localIterations << " of max. " << this->maximalNumberOfIterations << " Iterations.");
+						STORM_LOG_INFO("Executed " << localIterations << " of max. " << this->maximalNumberOfIterations << " Iterations.");
 					}
 
 
@@ -289,9 +289,9 @@ namespace storm {
 
 				// Check if the solver converged and issue a warning otherwise.
 				if (converged) {
-					LOG4CPLUS_INFO(logger, "Iterative solver converged after " << currentMaxLocalIterations << " iterations.");
+					STORM_LOG_INFO("Iterative solver converged after " << currentMaxLocalIterations << " iterations.");
 				} else {
-					LOG4CPLUS_WARN(logger, "Iterative solver did not converged after " << currentMaxLocalIterations << " iterations.");
+					STORM_LOG_WARN("Iterative solver did not converged after " << currentMaxLocalIterations << " iterations.");
 				}
 			}
         }
diff --git a/src/utility/ErrorHandling.h b/src/utility/ErrorHandling.h
index 5b9b50bdc..9bc228d6e 100644
--- a/src/utility/ErrorHandling.h
+++ b/src/utility/ErrorHandling.h
@@ -49,7 +49,7 @@ std::string demangle(char const* symbol) {
 	if (!SymInitialize(hProcess, NULL, TRUE)) {
 		// SymInitialize failed
 		error = GetLastError();
-		LOG4CPLUS_ERROR(logger, "SymInitialize returned error : " << error);
+		STORM_LOG_ERROR("SymInitialize returned error : " << error);
 		return FALSE;
 	} else {
 		char demangled[1024];
@@ -58,7 +58,7 @@ std::string demangle(char const* symbol) {
 		} else {
 			// UnDecorateSymbolName failed
 			DWORD error = GetLastError();
-			LOG4CPLUS_ERROR(logger, "UnDecorateSymbolName returned error: " << error);
+			STORM_LOG_ERROR("UnDecorateSymbolName returned error: " << error);
 		}
 	}
 #endif
@@ -87,7 +87,7 @@ void printUsage();
  * @param sig The code of the signal that needs to be handled.
  */
 void signalHandler(int sig) {
-	LOG4CPLUS_FATAL(logger, "The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal.");
+	STORM_LOG_ERROR("The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal.");
     printUsage();
 #ifndef WINDOWS
 #	define SIZE 128
@@ -106,13 +106,13 @@ void signalHandler(int sig) {
     // Starting this for-loop at j=2 means that we skip the handler itself. Currently this is not
     // done.
 	for (int j = 1; j < nptrs; j++) {
-		LOG4CPLUS_FATAL(logger, nptrs-j << ": " << demangle(strings[j]));
+		STORM_LOG_ERROR(nptrs-j << ": " << demangle(strings[j]));
 	}
 	free(strings);
 #else
-	LOG4CPLUS_WARN(logger, "No Backtrace Support available on Platform Windows!");
+	STORM_LOG_WARN("No Backtrace Support available on Platform Windows!");
 #endif
-	LOG4CPLUS_FATAL(logger, "Exiting.");
+	STORM_LOG_ERROR("Exiting.");
 	exit(2);
 }
 
diff --git a/src/utility/cstring.cpp b/src/utility/cstring.cpp
index 71bcbe69a..d80059e94 100644
--- a/src/utility/cstring.cpp
+++ b/src/utility/cstring.cpp
@@ -25,8 +25,8 @@ namespace cstring {
 uint_fast64_t checked_strtol(char const* str, char const** end) {
 	uint_fast64_t res = strtol(str, const_cast<char**>(end), 10);
 	if (str == *end) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number.");
-		LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
+		STORM_LOG_ERROR("Error while parsing integer. Next input token is not a number.");
+		STORM_LOG_ERROR("\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
 		throw storm::exceptions::WrongFormatException("Error while parsing integer. Next input token is not a number.");
 	}
 	return res;
@@ -43,8 +43,8 @@ uint_fast64_t checked_strtol(char const* str, char const** end) {
 double checked_strtod(char const* str, char const** end) {
 	double res = strtod(str, const_cast<char**>(end));
 	if (str == *end) {
-		LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number.");
-		LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
+		STORM_LOG_ERROR("Error while parsing floating point. Next input token is not a number.");
+		STORM_LOG_ERROR("\tUpcoming input is: \"" << std::string(str, 0, 16) << "\"");
 		throw storm::exceptions::WrongFormatException("Error while parsing floating point. Next input token is not a number.");
 	}
 	return res;
diff --git a/src/utility/graph.cpp b/src/utility/graph.cpp
index 0aa8b2836..e4839b1aa 100644
--- a/src/utility/graph.cpp
+++ b/src/utility/graph.cpp
@@ -829,7 +829,7 @@ namespace storm {
             template <typename T>
             std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<T> const& matrix) {
                 if (matrix.getRowCount() != matrix.getColumnCount()) {
-                    LOG4CPLUS_ERROR(logger, "Provided matrix is required to be square.");
+                    STORM_LOG_ERROR("Provided matrix is required to be square.");
                     throw storm::exceptions::InvalidArgumentException() << "Provided matrix is required to be square.";
                 }
                 
@@ -903,7 +903,7 @@ namespace storm {
                                                                                   storm::storage::BitVector const& startingStates,
                                                                                   storm::storage::BitVector const* filterStates) {
                 
-                LOG4CPLUS_INFO(logger, "Performing Dijkstra search.");
+                STORM_LOG_INFO("Performing Dijkstra search.");
                 
                 const uint_fast64_t noPredecessorValue = storm::utility::zero<uint_fast64_t>();
                 std::vector<T> probabilities(model.getNumberOfStates(), storm::utility::zero<T>());
@@ -949,7 +949,7 @@ namespace storm {
                 std::pair<std::vector<T>, std::vector<uint_fast64_t>> result;
                 result.first = std::move(probabilities);
                 result.second = std::move(predecessors);
-                LOG4CPLUS_INFO(logger, "Done performing Dijkstra search.");
+                STORM_LOG_INFO("Done performing Dijkstra search.");
                 return result;
             }
             
diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
index b293e2a4f..b2a39f5dd 100644
--- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
+++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
@@ -78,7 +78,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) {
 	EXPECT_NEAR(0.9993949793, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
 
     labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
-    auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
+    auto reachabilityRewardFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula, storm::logic::FormulaContext::Reward);
 
     result = checker.check(*reachabilityRewardFormula);
     storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();
diff --git a/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp b/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp
index eda9620df..23949131a 100644
--- a/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp
+++ b/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp
@@ -79,7 +79,7 @@ TEST(NativeDtmcPrctlModelCheckerTest, SynchronousLeader) {
     EXPECT_NEAR(0.9993949793, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision());
     
     labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected");
-    auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula);
+    auto reachabilityRewardFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula, storm::logic::FormulaContext::Reward);
     
     result = checker.check(*reachabilityRewardFormula);
     storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>();

From 5b6dcd0eed4fb795c810ab41f947ccb2fb57af92 Mon Sep 17 00:00:00 2001
From: Mavo <matthias.volk@rwth-aachen.de>
Date: Wed, 24 Feb 2016 18:14:18 +0100
Subject: [PATCH 13/23] UsageIndex is number of used child now

Former-commit-id: 629aeae3182982c94900a8b890f4a1b81ac8021c
---
 examples/dft/spare_symmetry.dft |  9 +++++++++
 src/storage/dft/DFT.cpp         | 29 +++++++++++++++++++++++++----
 src/storage/dft/DFT.h           | 12 +++++++++++-
 src/storage/dft/DFTElements.h   |  4 ++--
 src/storage/dft/DFTState.cpp    | 15 +++++++++++++--
 src/storage/dft/DFTState.h      | 11 +++++++++--
 6 files changed, 69 insertions(+), 11 deletions(-)
 create mode 100644 examples/dft/spare_symmetry.dft

diff --git a/examples/dft/spare_symmetry.dft b/examples/dft/spare_symmetry.dft
new file mode 100644
index 000000000..04b5c253b
--- /dev/null
+++ b/examples/dft/spare_symmetry.dft
@@ -0,0 +1,9 @@
+toplevel "A";
+"A" and "B" "C";
+"B" wsp "I" "J";
+"C" wsp "K" "L";
+"I" lambda=0.5 dorm=0.3;
+"J" lambda=0.5 dorm=0.3;
+"K" lambda=0.5 dorm=0.3;
+"L" lambda=0.5 dorm=0.3;
+
diff --git a/src/storage/dft/DFT.cpp b/src/storage/dft/DFT.cpp
index eef83928d..2924789fd 100644
--- a/src/storage/dft/DFT.cpp
+++ b/src/storage/dft/DFT.cpp
@@ -11,7 +11,7 @@ namespace storm {
     namespace storage {
 
         template<typename ValueType>
-        DFT<ValueType>::DFT(DFTElementVector const& elements, DFTElementPointer const& tle) : mElements(elements), mNrOfBEs(0), mNrOfSpares(0), mTopLevelIndex(tle->id()) {
+        DFT<ValueType>::DFT(DFTElementVector const& elements, DFTElementPointer const& tle) : mElements(elements), mNrOfBEs(0), mNrOfSpares(0), mTopLevelIndex(tle->id()), mMaxSpareChildCount(0) {
             assert(elementIndicesCorrect());
             size_t nrRepresentatives = 0;
             
@@ -25,6 +25,7 @@ namespace storm {
                 else if (elem->isSpareGate()) {
                     ++mNrOfSpares;
                     bool firstChild = true;
+                    mMaxSpareChildCount = std::max(mMaxSpareChildCount, std::static_pointer_cast<DFTSpare<ValueType>>(elem)->children().size());
                     for(auto const& spareReprs : std::static_pointer_cast<DFTSpare<ValueType>>(elem)->children()) {
                         std::set<size_t> module = {spareReprs->id()};
                         spareReprs->extendSpareModule(module);
@@ -63,7 +64,9 @@ namespace storm {
             }
             mTopModule = std::vector<size_t>(topModuleSet.begin(), topModuleSet.end());
             
-            size_t usageInfoBits = mElements.size() > 1 ? storm::utility::math::uint64_log2(mElements.size()-1) + 1 : 1;
+            //Reserve space for failed spares
+            ++mMaxSpareChildCount;
+            size_t usageInfoBits = storm::utility::math::uint64_log2(mMaxSpareChildCount) + 1;
             mStateVectorSize = nrElements() * 2 + mNrOfSpares * usageInfoBits + nrRepresentatives;
         }
 
@@ -73,7 +76,7 @@ namespace storm {
             // Collect all elements in the first subtree
             // TODO make recursive to use for nested subtrees
 
-            DFTStateGenerationInfo generationInfo(nrElements());
+            DFTStateGenerationInfo generationInfo(nrElements(), mMaxSpareChildCount);
 
             // Perform DFS and insert all elements of subtree sequentially
             size_t stateIndex = 0;
@@ -296,7 +299,25 @@ namespace storm {
             }
             return stream.str();
         }
-
+        
+        template<typename ValueType>
+        size_t DFT<ValueType>::getChild(size_t spareId, size_t nrUsedChild) const {
+            assert(mElements[spareId]->isSpareGate());
+            return getGate(spareId)->children()[nrUsedChild]->id();
+        }
+        
+        template<typename ValueType>
+        size_t DFT<ValueType>::getNrChild(size_t spareId, size_t childId) const {
+            assert(mElements[spareId]->isSpareGate());
+            DFTElementVector children = getGate(spareId)->children();
+            for (size_t nrChild = 0; nrChild < children.size(); ++nrChild) {
+                if (children[nrChild]->id() == childId) {
+                    return nrChild;
+                }
+            }
+            assert(false);
+        }
+        
         template <typename ValueType>
         std::vector<size_t> DFT<ValueType>::getIndependentSubDftRoots(size_t index) const {
             auto elem = getElement(index);
diff --git a/src/storage/dft/DFT.h b/src/storage/dft/DFT.h
index 453db1443..48bb60f68 100644
--- a/src/storage/dft/DFT.h
+++ b/src/storage/dft/DFT.h
@@ -45,7 +45,8 @@ namespace storm {
             
         public:
             
-            DFTStateGenerationInfo(size_t nrElements) : mUsageInfoBits(nrElements > 1 ? storm::utility::math::uint64_log2(nrElements-1) + 1 : 1), mIdToStateIndex(nrElements) {
+            DFTStateGenerationInfo(size_t nrElements, size_t maxSpareChildCount) : mUsageInfoBits(storm::utility::math::uint64_log2(maxSpareChildCount) + 1), mIdToStateIndex(nrElements) {
+                assert(maxSpareChildCount < pow(2, mUsageInfoBits));
             }
 
             size_t usageInfoBits() const {
@@ -144,6 +145,7 @@ namespace storm {
             size_t mNrOfSpares;
             size_t mTopLevelIndex;
             size_t mStateVectorSize;
+            size_t mMaxSpareChildCount;
             std::map<size_t, std::vector<size_t>> mSpareModules;
             std::vector<size_t> mDependencies;
             std::vector<size_t> mTopModule;
@@ -175,6 +177,10 @@ namespace storm {
                 return mTopLevelIndex;
             }
             
+            size_t getMaxSpareChildCount() const {
+                return mMaxSpareChildCount;
+            }
+            
             std::vector<size_t> getSpareIndices() const {
                 std::vector<size_t> indices;
                 for(auto const& elem : mElements) {
@@ -288,6 +294,10 @@ namespace storm {
                 return storm::storage::DFTState<ValueType>::isFailsafe(state, stateGenerationInfo.getStateIndex(mTopLevelIndex));
             }
             
+            size_t getChild(size_t spareId, size_t nrUsedChild) const;
+            
+            size_t getNrChild(size_t spareId, size_t childId) const;
+            
             std::string getElementsString() const;
 
             std::string getInfoString() const;
diff --git a/src/storage/dft/DFTElements.h b/src/storage/dft/DFTElements.h
index 3236a5551..48318d0ae 100644
--- a/src/storage/dft/DFTElements.h
+++ b/src/storage/dft/DFTElements.h
@@ -412,12 +412,12 @@ namespace storm {
             }
 
             /**
-             * Finish failed/failsafe spare gate by activating the children and setting the useIndex to the spare id.
+             * Finish failed/failsafe spare gate by activating the children and setting the useIndex to the maximum value.
              * This prevents multiple fail states with different usages or activations.
              * @param state The current state.
              */
             void finalizeSpare(DFTState<ValueType>& state) const {
-                state.setUses(this->mId, this->mId);
+                state.finalizeUses(this->mId);
                 for (auto child : this->children()) {
                     if (!state.isActive(child->id())) {
                         state.activate(child->id());
diff --git a/src/storage/dft/DFTState.cpp b/src/storage/dft/DFTState.cpp
index be5c33060..8af84255c 100644
--- a/src/storage/dft/DFTState.cpp
+++ b/src/storage/dft/DFTState.cpp
@@ -201,7 +201,12 @@ namespace storm {
 
         template<typename ValueType>
         uint_fast64_t DFTState<ValueType>::uses(size_t id) const {
-            return extractUses(mStateGenerationInfo.getSpareUsageIndex(id));
+            size_t nrUsedChild = extractUses(mStateGenerationInfo.getSpareUsageIndex(id));
+            if (nrUsedChild == mDft.getMaxSpareChildCount()) {
+                return id;
+            } else {
+                return mDft.getChild(id, nrUsedChild);
+            }
         }
 
         template<typename ValueType>
@@ -217,9 +222,15 @@ namespace storm {
 
         template<typename ValueType>
         void DFTState<ValueType>::setUses(size_t spareId, size_t child) {
-            mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), child);
+            mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getNrChild(spareId, child));
             mUsedRepresentants.push_back(child);
         }
+        
+        template<typename ValueType>
+        void DFTState<ValueType>::finalizeUses(size_t spareId) {
+            assert(hasFailed(spareId));
+            mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getMaxSpareChildCount());
+        }
 
         template<typename ValueType>
         bool DFTState<ValueType>::claimNew(size_t spareId, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children) {
diff --git a/src/storage/dft/DFTState.h b/src/storage/dft/DFTState.h
index eccf7f01d..ea874cf1b 100644
--- a/src/storage/dft/DFTState.h
+++ b/src/storage/dft/DFTState.h
@@ -93,9 +93,10 @@ namespace storm {
             }
            
             /**
-             * This method gets the usage information for a spare
+             * This method returns the id of the used child for a spare. If no element is used, it returns the given id.
              * @param id Id of the spare
-             * @return The child that currently is used.
+             * @return The id of the currently used child or if non is used (because of spare failure) the id of
+             * the spare.
              */
             uint_fast64_t uses(size_t id) const;
             
@@ -120,6 +121,12 @@ namespace storm {
              */
             void setUses(size_t spareId, size_t child);
             
+            /**
+             * Sets the use for the spare to a default value to gain consistent states after failures.
+             * @param spareId Id of the spare
+             */
+            void finalizeUses(size_t spareId);
+            
             bool claimNew(size_t spareId, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children);
             
             bool hasOutgoingEdges() const {

From d32d90de5b7f5a75062ecd1146077b99d4c0489c Mon Sep 17 00:00:00 2001
From: Mavo <matthias.volk@rwth-aachen.de>
Date: Wed, 24 Feb 2016 18:18:19 +0100
Subject: [PATCH 14/23] Fixed some compile warnings

Former-commit-id: 91055b14cff62f8a06b7cbfad79f504a83f44563
---
 src/storage/dft/DFT.h                     | 4 ++--
 src/storage/dft/elements/DFTRestriction.h | 2 +-
 src/storm-dyftee.cpp                      | 1 -
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/storage/dft/DFT.h b/src/storage/dft/DFT.h
index 48bb60f68..7d10b2ee1 100644
--- a/src/storage/dft/DFT.h
+++ b/src/storage/dft/DFT.h
@@ -81,8 +81,8 @@ namespace storm {
                 return mSpareActivationIndex.at(id);
             }
             
-            size_t addSymmetry(size_t lenght, std::vector<size_t>& startingIndices) {
-                mSymmetries.push_back(std::make_pair(lenght, startingIndices));
+            void addSymmetry(size_t length, std::vector<size_t>& startingIndices) {
+                mSymmetries.push_back(std::make_pair(length, startingIndices));
             }
             
             size_t getSymmetrySize() const {
diff --git a/src/storage/dft/elements/DFTRestriction.h b/src/storage/dft/elements/DFTRestriction.h
index 46b6e23cc..d0482e4a7 100644
--- a/src/storage/dft/elements/DFTRestriction.h
+++ b/src/storage/dft/elements/DFTRestriction.h
@@ -183,7 +183,7 @@ namespace storm {
 
             }
             
-            bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) {
+            bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
                 
             }
 
diff --git a/src/storm-dyftee.cpp b/src/storm-dyftee.cpp
index ba50d90f3..07bff5732 100644
--- a/src/storm-dyftee.cpp
+++ b/src/storm-dyftee.cpp
@@ -32,7 +32,6 @@ void analyzeDFT(std::string filename, std::string property, bool symred = false)
     std::map<size_t, std::vector<std::vector<size_t>>> emptySymmetry;
     storm::storage::DFTIndependentSymmetries symmetries(emptySymmetry);
     if(symred) {
-        std::cout << dft.getElementsString() << std::endl;
         auto colouring = dft.colourDFT();
         symmetries = dft.findSymmetries(colouring);
         std::cout << "Symmetries: " << symmetries << std::endl;

From e0980de0ba6f39fcbdeca662ccfb1b6ac64c79f7 Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Wed, 24 Feb 2016 19:14:33 +0100
Subject: [PATCH 15/23] first version of storm without log4cplus as a
 dependency

Former-commit-id: 5aa64fabd71b7f6a02b46de3336d1f1b55de74d6
---
 CMakeLists.txt                                |  30 +++--
 src/adapters/GmmxxAdapter.h                   |   5 +-
 src/cli/cli.cpp                               |  12 +-
 .../AtomicPropositionLabelingParser.cpp       |   4 -
 .../DeterministicSparseTransitionParser.cpp   |   6 +-
 src/parser/MappedFile.cpp                     |   6 +-
 src/parser/MarkovAutomatonParser.cpp          |   4 -
 src/parser/NondeterministicModelParser.cpp    |   1 +
 ...NondeterministicSparseTransitionParser.cpp |   6 +-
 src/parser/SparseStateRewardParser.cpp        |   6 +-
 .../TopologicalMinMaxLinearEquationSolver.cpp |   6 +-
 src/storage/ModelFormulasPair.h               |   2 +-
 src/storage/SparseMatrix.cpp                  |   4 -
 src/utility/cstring.cpp                       |   6 +-
 src/utility/graph.cpp                         |   6 +-
 src/utility/initialize.cpp                    |  12 +-
 src/utility/initialize.h                      |   7 +-
 src/utility/macros.h                          | 127 +++++++++++++++++-
 storm-config.h.in                             |   1 +
 19 files changed, 170 insertions(+), 81 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b297bca7c..c17fb7774 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,6 +28,7 @@ option(USE_LIBCXX "Sets whether the standard library is libc++." OFF)
 option(USE_CARL "Sets whether carl should be included." ON)
 option(FORCE_COLOR "Force color output" OFF)
 option(STORM_COMPILE_WITH_CCACHE "Compile using CCache" ON)
+option(STORM_LOGGING_FRAMEWORK "Use a framework for logging" OFF)
 set(GUROBI_ROOT "" CACHE STRING "A hint to the root directory of Gurobi (optional).")
 set(Z3_ROOT "" CACHE STRING "A hint to the root directory of Z3 (optional).")
 set(CUDA_ROOT "" CACHE STRING "The root directory of CUDA.")
@@ -573,20 +574,21 @@ endif()
 ##	Log4CPlus
 ##
 #############################################################
-set(BUILD_SHARED_LIBS OFF CACHE BOOL "If TRUE, log4cplus is built as a shared library, otherwise as a static library")
-set(LOG4CPLUS_BUILD_LOGGINGSERVER OFF)
-set(LOG4CPLUS_BUILD_TESTING OFF)
-set(LOG4CPLUS_USE_UNICODE OFF)
-set(LOG4CPLUS_DEFINE_INSTALL_TARGET OFF)
-add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1")
-include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include")
-include_directories("${PROJECT_BINARY_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") # This adds the defines.hxx file
-
-list(APPEND STORM_LINK_LIBRARIES log4cplusS)
-if (UNIX AND NOT APPLE)
-    list(APPEND STORM_LINK_LIBRARIES rt)
-endif(UNIX AND NOT APPLE)
-
+if(STORM_LOGGING_FRAMEWORK) 
+    set(BUILD_SHARED_LIBS OFF CACHE BOOL "If TRUE, log4cplus is built as a shared library, otherwise as a static library")
+    set(LOG4CPLUS_BUILD_LOGGINGSERVER OFF)
+    set(LOG4CPLUS_BUILD_TESTING OFF)
+    set(LOG4CPLUS_USE_UNICODE OFF)
+    set(LOG4CPLUS_DEFINE_INSTALL_TARGET OFF)
+    add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1")
+    include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include")
+    include_directories("${PROJECT_BINARY_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") # This adds the defines.hxx file
+
+    list(APPEND STORM_LINK_LIBRARIES log4cplusS)
+    if (UNIX AND NOT APPLE)
+        list(APPEND STORM_LINK_LIBRARIES rt)
+    endif(UNIX AND NOT APPLE)
+endif()
 #############################################################
 ##
 ##	Intel Threading Building Blocks (optional)
diff --git a/src/adapters/GmmxxAdapter.h b/src/adapters/GmmxxAdapter.h
index df81b46f7..ad4c82a0e 100644
--- a/src/adapters/GmmxxAdapter.h
+++ b/src/adapters/GmmxxAdapter.h
@@ -16,10 +16,7 @@
 #include "src/storage/SparseMatrix.h"
 #include "src/utility/ConversionHelper.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-
-extern log4cplus::Logger logger;
+#include "src/utility/macros.h"
 
 namespace storm {
 
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index 758ac9a2a..0b384b539 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -186,18 +186,14 @@ namespace storm {
                 }
                 
                 if (storm::settings::generalSettings().isVerboseSet()) {
-                    logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL);
-                    LOG4CPLUS_INFO(logger, "Enabled verbose mode, log output gets printed to console.");
+                    STORM_GLOBAL_LOGLEVEL_INFO();
                 }
                 if (storm::settings::debugSettings().isDebugSet()) {
-                    logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL);
-                    logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::DEBUG_LOG_LEVEL);
-                    LOG4CPLUS_INFO(logger, "Enabled very verbose mode, log output gets printed to console.");
+                    STORM_GLOBAL_LOGLEVEL_DEBUG();
+                    
                 }
                 if (storm::settings::debugSettings().isTraceSet()) {
-                    logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL);
-                    logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::TRACE_LOG_LEVEL);
-                    LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console.");
+                    STORM_GLOBAL_LOGLEVEL_TRACE();
                 }
                 if (storm::settings::debugSettings().isLogfileSet()) {
                     storm::utility::initializeFileLogging();
diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp
index 349bfb56b..090a568b7 100644
--- a/src/parser/AtomicPropositionLabelingParser.cpp
+++ b/src/parser/AtomicPropositionLabelingParser.cpp
@@ -16,10 +16,6 @@
 #include "src/exceptions/WrongFormatException.h"
 #include "src/exceptions/FileIoException.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
 namespace storm {
 	namespace parser {
 
diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp
index f18b46441..da200fe2e 100644
--- a/src/parser/DeterministicSparseTransitionParser.cpp
+++ b/src/parser/DeterministicSparseTransitionParser.cpp
@@ -17,11 +17,7 @@
 #include "src/settings/modules/GeneralSettings.h"
 
 #include "src/adapters/CarlAdapter.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "src/utility/macros.h"
 namespace storm {
     namespace parser {
 
diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp
index 86f2648eb..b4e8f30f0 100644
--- a/src/parser/MappedFile.cpp
+++ b/src/parser/MappedFile.cpp
@@ -14,11 +14,7 @@
 #include <boost/integer/integer_mask.hpp>
 
 #include "src/exceptions/FileIoException.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "src/utility/macros.h"
 namespace storm {
 	namespace parser {
 
diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp
index b4ee7be34..37eeacbcd 100644
--- a/src/parser/MarkovAutomatonParser.cpp
+++ b/src/parser/MarkovAutomatonParser.cpp
@@ -8,10 +8,6 @@
 
 #include "src/adapters/CarlAdapter.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
 namespace storm {
     namespace parser {
 
diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp
index 220451c33..b2d539c3a 100644
--- a/src/parser/NondeterministicModelParser.cpp
+++ b/src/parser/NondeterministicModelParser.cpp
@@ -11,6 +11,7 @@
 #include "src/parser/SparseChoiceLabelingParser.h"
 
 #include "src/adapters/CarlAdapter.h"
+#include "src/utility/macros.h"
 
 namespace storm {
     namespace parser {
diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp
index 89322808c..e89fe76e2 100644
--- a/src/parser/NondeterministicSparseTransitionParser.cpp
+++ b/src/parser/NondeterministicSparseTransitionParser.cpp
@@ -14,11 +14,7 @@
 #include "src/utility/cstring.h"
 
 #include "src/adapters/CarlAdapter.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "src/utility/macros.h"
 namespace storm {
     namespace parser {
 
diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp
index 35e1c3d59..2207813ab 100644
--- a/src/parser/SparseStateRewardParser.cpp
+++ b/src/parser/SparseStateRewardParser.cpp
@@ -8,11 +8,7 @@
 #include "src/parser/MappedFile.h"
 
 #include "src/adapters/CarlAdapter.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "src/utility/macros.h"
 namespace storm {
     namespace parser {
 
diff --git a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp
index bb912371b..793842849 100644
--- a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp
+++ b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp
@@ -13,11 +13,7 @@
 #include "src/settings/modules/NativeEquationSolverSettings.h"
 #include "src/settings/modules/TopologicalValueIterationEquationSolverSettings.h"
 
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "src/utility/macros.h"
 #include "storm-config.h"
 #ifdef STORM_HAVE_CUDA
 #	include "cudaForStorm.h"
diff --git a/src/storage/ModelFormulasPair.h b/src/storage/ModelFormulasPair.h
index 490116c46..fab8cb3d1 100644
--- a/src/storage/ModelFormulasPair.h
+++ b/src/storage/ModelFormulasPair.h
@@ -1,6 +1,6 @@
 #pragma once
 #include "../models/ModelBase.h"
-
+#include <vector>
 
 namespace storm {
     namespace logic {
diff --git a/src/storage/SparseMatrix.cpp b/src/storage/SparseMatrix.cpp
index 253609210..3dbabf854 100644
--- a/src/storage/SparseMatrix.cpp
+++ b/src/storage/SparseMatrix.cpp
@@ -22,10 +22,6 @@
 
 #include "src/utility/macros.h"
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
 namespace storm {
     namespace storage {
         
diff --git a/src/utility/cstring.cpp b/src/utility/cstring.cpp
index d80059e94..f27ca73a4 100644
--- a/src/utility/cstring.cpp
+++ b/src/utility/cstring.cpp
@@ -3,11 +3,7 @@
 #include <cstring>
 
 #include "src/exceptions/WrongFormatException.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-extern log4cplus::Logger logger;
-
+#include "src/utility/macros.h"
 namespace storm {
 
 namespace utility {
diff --git a/src/utility/graph.cpp b/src/utility/graph.cpp
index e4839b1aa..de920ad21 100644
--- a/src/utility/graph.cpp
+++ b/src/utility/graph.cpp
@@ -16,11 +16,7 @@
 #include "src/storage/dd/Bdd.h"
 #include "src/storage/dd/Add.h"
 #include "src/storage/dd/DdManager.h"
-
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-
-extern log4cplus::Logger logger;
+#include "src/utility/macros.h"
 
 namespace storm {
     namespace utility {
diff --git a/src/utility/initialize.cpp b/src/utility/initialize.cpp
index d5cbb58db..72e3fd964 100644
--- a/src/utility/initialize.cpp
+++ b/src/utility/initialize.cpp
@@ -4,19 +4,26 @@
 #include "src/settings/SettingsManager.h"
 #include "src/settings/modules/DebugSettings.h"
 
-
+#ifdef STORM_LOGGING_FRAMEWORK
 log4cplus::Logger logger;
 log4cplus::Logger printer;
+#else 
+int storm_runtime_loglevel = STORM_LOGLEVEL_WARN;
+#endif
+
 
 namespace storm {
     namespace utility {
 
 
        void initializeLogger() {
+#ifdef STORM_LOGGING_FRAMEWORK
             auto loglevel = storm::settings::debugSettings().isTraceSet() ? log4cplus::TRACE_LOG_LEVEL : storm::settings::debugSettings().isDebugSet() ? log4cplus::DEBUG_LOG_LEVEL : log4cplus::WARN_LOG_LEVEL;
             initializeLogger(loglevel);
+#endif
        }
 
+#ifdef STORM_LOGGING_FRAMEWORK
         void initializeLogger(log4cplus::LogLevel const& loglevel) {
             logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
             log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender());
@@ -26,6 +33,7 @@ namespace storm {
             logger.setLogLevel(loglevel);
             consoleLogAppender->setThreshold(loglevel);
         }
+#endif
 
         void setUp() {
             initializeLogger();
@@ -37,10 +45,12 @@ namespace storm {
         }
 
         void initializeFileLogging() {
+#ifdef STORM_LOGGING_FRAMEWORK
             log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender(storm::settings::debugSettings().getLogfilename()));
             fileLogAppender->setName("mainFileAppender");
             fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M:%S} (%r ms) - %F:%L: %m%n")));
             logger.addAppender(fileLogAppender);
+#endif
         }
 
     }
diff --git a/src/utility/initialize.h b/src/utility/initialize.h
index 06fa8c2fa..dac87fa74 100644
--- a/src/utility/initialize.h
+++ b/src/utility/initialize.h
@@ -4,10 +4,6 @@
 
 
 
-#include "log4cplus/logger.h"
-#include "log4cplus/loggingmacros.h"
-#include "log4cplus/consoleappender.h"
-#include "log4cplus/fileappender.h"
 #include "macros.h"
 
 #include "src/settings/SettingsManager.h"
@@ -19,8 +15,9 @@ namespace storm {
          * Initializes the logging framework and sets up logging to console.
          */
         void initializeLogger();
+#ifdef STORM_LOGGING_FRAMEWORK
         void initializeLogger(log4cplus::LogLevel const&);
-
+#endif
         /*!
          * Performs some necessary initializations.
          */
diff --git a/src/utility/macros.h b/src/utility/macros.h
index 037d1882b..79293f3ea 100644
--- a/src/utility/macros.h
+++ b/src/utility/macros.h
@@ -2,12 +2,113 @@
 #define STORM_UTILITY_MACROS_H_
 
 #include <cassert>
+#include "storm-config.h"
 
+#ifndef STORM_LOGGING_FRAMEWORK
+#include <iostream>
+#include <sstream>
+
+extern int storm_runtime_loglevel;
+
+#define STORM_LOGLEVEL_ERROR 0
+#define STORM_LOGLEVEL_WARN 1
+#define STORM_LOGLEVEL_INFO 2
+#define STORM_LOGLEVEL_DEBUG 3
+#define STORM_LOGLEVEL_TRACE 4
+
+#define STORM_LOG_DEBUG(message)                                    \
+do {                                                                \
+    if(storm_runtime_loglevel <= STORM_LOGLEVEL_DEBUG) {            \
+        std::cout << "LOG DBG: " << message << std::endl;           \
+    }                                                               \
+} while (false)
+
+#define STORM_LOG_TRACE(message)                        \
+do {                                                    \
+    std::cout << "LOG TRC: " << message << std::endl;  \
+} while(false)  
+
+
+// Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set.
+#ifndef NDEBUG
+#define STORM_LOG_ASSERT(cond, message)         \
+do {                                            \
+if (!(cond)) {                                  \
+std::cout << "LOG ERR: " << message << std::endl;          \
+assert(cond);                                   \
+}                                               \
+} while (false)                                 \
+
+#else
+#define STORM_LOG_ASSERT(cond, message)         
+#endif
+// Define STORM_LOG_THROW to always throw the exception with the given message if the condition fails to hold.
+#define STORM_LOG_THROW(cond, exception, message)     \
+do {                                            \
+    if (!(cond)) {                              \
+        std::cout << "LOG ERR: " << message << std::endl;       \
+        throw exception() << message;           \
+    }                                           \
+} while (false)                                 \
+
+
+// Define STORM_LOG_WARN, STORM_LOG_ERROR and STORM_LOG_INFO to log the given message with the corresponding log levels.
+#define STORM_LOG_WARN(message)                 \
+do {                                            \
+    std::cout << "LOG WRN: " << message << std::endl;           \
+} while (false)                                 \
+
+#define STORM_LOG_WARN_COND(cond, message)      \
+do {                                            \
+    if (!(cond)) {                              \
+        std::cout << "LOG WRN: " << message << std::endl;       \
+    }                                           \
+} while (false)                                 \
+
+#define STORM_LOG_INFO(message)                 \
+do {                                            \
+    std::cout << "LOG INF: " << message << std::endl;            \
+} while (false)                                 \
+
+#define STORM_LOG_INFO_COND(cond, message)      \
+do {                                            \
+    if (!(cond)) {                              \
+        std::cout << "LOG INF: " << message << std::endl;        \
+    }                                           \
+} while (false)                                 \
+
+#define STORM_LOG_ERROR(message)                \
+do {                                                \
+    std::stringstream __ss;                         \
+     __ss << message;                 \
+     std::cout << "LOG ERR: " << __ss.str() << std::endl;          \
+} while (false)                                 \
+
+#define STORM_LOG_ERROR_COND(cond, message)     \
+do {                                            \
+    if (!(cond)) {                              \
+        STORM_LOG_ERROR(message)        \
+    }                                           \
+} while (false)                                 \
+
+#define STORM_GLOBAL_LOGLEVEL_INFO() \
+do { \
+} while (false)
+
+#define STORM_GLOBAL_LOGLEVEL_DEBUG() \
+do { \
+} while(false)
+    
+#define STORM_GLOBAL_LOGLEVEL_TRACE() \
+do { \
+} while(false)
+
+
+#else 
 // Include the parts necessary for Log4cplus.
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 extern log4cplus::Logger logger;
-
 /*!
  * Define the macros STORM_LOG_DEBUG and STORM_LOG_TRACE.
  */
@@ -81,6 +182,30 @@ do {                                            \
     }                                           \
 } while (false)                                 \
 
+
+#define STORM_GLOBAL_LOGLEVEL_INFO() \
+do { \
+logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); \
+LOG4CPLUS_INFO(logger, "Enabled verbose mode, log output gets printed to console."); \
+} while (false)
+
+#define STORM_GLOBAL_LOGLEVEL_DEBUG() \
+do { \
+logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); \
+logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::DEBUG_LOG_LEVEL); \
+LOG4CPLUS_INFO(logger, "Enabled very verbose mode, log output gets printed to console."); \
+} while(false)
+    
+#define STORM_GLOBAL_LOGLEVEL_TRACE() \
+do { \
+logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL); \
+logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::TRACE_LOG_LEVEL); \
+LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console."); \
+} while(false)
+
+
+
+#endif
 /*!
  * Define the macros that print information and optionally also log it.
  */
diff --git a/storm-config.h.in b/storm-config.h.in
index ec45f1445..e7fbd50e6 100644
--- a/storm-config.h.in
+++ b/storm-config.h.in
@@ -44,5 +44,6 @@
 // Whether smtrat is available and to be used. 
 #cmakedefine STORM_HAVE_SMTRAT
 
+#cmakedefine STORM_LOGGING_FRAMEWORK
 
 #endif // STORM_GENERATED_STORMCONFIG_H_

From e0379b9c50668e1dc565f2b2b989dfd2e8d20965 Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Wed, 24 Feb 2016 22:25:15 +0100
Subject: [PATCH 16/23] Log CUDD build process

Former-commit-id: daf41bb2654b99a08699160937c6218cb18bce8e
---
 resources/3rdparty/CMakeLists.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt
index fadcbd3f6..d62f72f95 100644
--- a/resources/3rdparty/CMakeLists.txt
+++ b/resources/3rdparty/CMakeLists.txt
@@ -32,6 +32,8 @@ ExternalProject_Add(
 )
 add_dependencies(resources glpk)
 
+set(GLPK_LIBRARIES  ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk${DYNAMIC_EXT} PARENT_SCOPE)
+set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include PARENT_SCOPE)
 
 ExternalProject_Add(
     cudd3
@@ -42,6 +44,9 @@ ExternalProject_Add(
     BUILD_COMMAND make "CFLAGS=-O2 -w"
     INSTALL_COMMAND make install
     BUILD_IN_SOURCE 0
+    LOG_CONFIGURE ON
+    LOG_BUILD ON
+    LOG_INSTALL ON
 )
 add_dependencies(resources cudd3)
 

From abac11ab5070d94f21ae97d2da894d321185b614 Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Wed, 24 Feb 2016 22:52:36 +0100
Subject: [PATCH 17/23] sylvan build stuff in 3rd party folder now

Former-commit-id: 3ea163dfeda863332440ff3ba19ae3d6747ed60e
---
 CMakeLists.txt                    | 21 +++------------------
 resources/3rdparty/CMakeLists.txt | 16 ++++++++++++++++
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c17fb7774..38c216d00 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -260,8 +260,6 @@ endif(STORM_HAVE_Z3)
 set(STORM_HAVE_GLPK 1)
 message (STATUS "StoRM - Linking with glpk")
 
-set(GLPK_LIBRARIES  ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk${DYNAMIC_EXT})
-set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include)
 include_directories(${GLPK_INCLUDE_DIR})
 list(APPEND STORM_LINK_LIBRARIES ${GLPK_LIBRARIES})
 
@@ -538,28 +536,15 @@ endif()
 ##
 #############################################################
 
-set(STORM_SYLVAN_ROOT "${PROJECT_SOURCE_DIR}/resources/3rdparty/sylvan")
-ExternalProject_Add(
-    sylvan
-    DOWNLOAD_COMMAND ""
-    PREFIX "sylvan"
-    SOURCE_DIR "${STORM_SYLVAN_ROOT}"
-    CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release
-    BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan"
-    INSTALL_COMMAND ""
-    INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan"
-)
-ExternalProject_Get_Property(sylvan binary_dir)
-set(Sylvan_INCLUDE_DIR "${STORM_SYLVAN_ROOT}/src")
 message(STATUS "Linking with shipped version of sylvan (in directory ${STORM_SYLVAN_ROOT}).")
 include_directories("${Sylvan_INCLUDE_DIR}")
-list(APPEND STORM_LINK_LIBRARIES "${binary_dir}/src/libsylvan.a")
+list(APPEND STORM_LINK_LIBRARIES ${Sylvan_LIBRARY})
 if(${OPERATING_SYSTEM} MATCHES "Linux")
 	find_package(Hwloc QUIET)
 	if(NOT Hwloc_FOUND)
-		message(SEND_ERROR "HWLOC is required but was not found.")
+            message(SEND_ERROR "HWLOC is required but was not found.")
 	else()
-		list(APPEND STORM_LINK_LIBRARIES ${Hwloc_LIBRARIES})	
+            list(APPEND STORM_LINK_LIBRARIES ${Hwloc_LIBRARIES})	
 	endif()
 endif()
 
diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt
index d62f72f95..d935a003f 100644
--- a/resources/3rdparty/CMakeLists.txt
+++ b/resources/3rdparty/CMakeLists.txt
@@ -56,6 +56,22 @@ set(CUDD3_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/include PARENT_SCOP
 set(CUDD3_SHARED_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/lib/libcudd${DYNAMIC_EXT} PARENT_SCOPE)
 set(CUDD3_STATIC_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/liblibcudd${STATIC_EXT} PARENT_SCOPE)
 
+set(STORM_SYLVAN_ROOT "${PROJECT_SOURCE_DIR}/resources/3rdparty/sylvan")
+ExternalProject_Add(
+    sylvan
+    DOWNLOAD_COMMAND ""
+    PREFIX "sylvan"
+    SOURCE_DIR "${STORM_SYLVAN_ROOT}"
+    CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release
+    BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan"
+    INSTALL_COMMAND ""
+    INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan"
+)
+ExternalProject_Get_Property(sylvan binary_dir)
+set(Sylvan_INCLUDE_DIR "${STORM_SYLVAN_ROOT}/src" PARENT_SCOPE)
+set(Sylvan_LIBRARY "${binary_dir}/src/libsylvan.a" PARENT_SCOPE)
+
+
 ExternalProject_Add(
         googletest
         #For downloads (may be useful later!)

From cf986311ad928c23f5691e9d03abad2aff6dee9a Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Wed, 24 Feb 2016 22:53:13 +0100
Subject: [PATCH 18/23] loglevel can be set now and all logging macros support
 streaming

Former-commit-id: c8c32b43e64da8e266c471f5d50ae8a3e6495397
---
 src/utility/macros.h | 130 ++++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 56 deletions(-)

diff --git a/src/utility/macros.h b/src/utility/macros.h
index 79293f3ea..769825139 100644
--- a/src/utility/macros.h
+++ b/src/utility/macros.h
@@ -18,92 +18,110 @@ extern int storm_runtime_loglevel;
 
 #define STORM_LOG_DEBUG(message)                                    \
 do {                                                                \
-    if(storm_runtime_loglevel <= STORM_LOGLEVEL_DEBUG) {            \
-        std::cout << "LOG DBG: " << message << std::endl;           \
+    if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) {            \
+        std::stringstream __ss;                                     \
+        __ss << message;                                            \
+        std::cout << "LOG DBG: " << __ss.str() << std::endl;        \
     }                                                               \
 } while (false)
 
-#define STORM_LOG_TRACE(message)                        \
-do {                                                    \
-    std::cout << "LOG TRC: " << message << std::endl;  \
+#define STORM_LOG_TRACE(message)                                \
+do {                                                            \
+    if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) {        \
+        std::stringstream __ss;                                 \
+        __ss << message;                                        \
+        std::cout << "LOG TRC: " << message << std::endl;       \
+    }                                                           \
 } while(false)  
 
 
 // Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set.
 #ifndef NDEBUG
-#define STORM_LOG_ASSERT(cond, message)         \
-do {                                            \
-if (!(cond)) {                                  \
-std::cout << "LOG ERR: " << message << std::endl;          \
-assert(cond);                                   \
-}                                               \
-} while (false)                                 \
+#define STORM_LOG_ASSERT(cond, message)                     \
+do {                                                        \
+if (!(cond)) {                                              \
+std::cout << "ASSERT FAILED: " << message << std::endl;     \
+assert(cond);                                               \
+}                                                           \
+} while (false)                                 
 
 #else
 #define STORM_LOG_ASSERT(cond, message)         
 #endif
 // Define STORM_LOG_THROW to always throw the exception with the given message if the condition fails to hold.
-#define STORM_LOG_THROW(cond, exception, message)     \
-do {                                            \
-    if (!(cond)) {                              \
+#define STORM_LOG_THROW(cond, exception, message)               \
+do {                                                            \
+    if (!(cond)) {                                              \
         std::cout << "LOG ERR: " << message << std::endl;       \
-        throw exception() << message;           \
-    }                                           \
-} while (false)                                 \
+        throw exception() << message;                           \
+    }                                                           \
+} while (false)                                
 
 
 // Define STORM_LOG_WARN, STORM_LOG_ERROR and STORM_LOG_INFO to log the given message with the corresponding log levels.
-#define STORM_LOG_WARN(message)                 \
-do {                                            \
-    std::cout << "LOG WRN: " << message << std::endl;           \
-} while (false)                                 \
-
-#define STORM_LOG_WARN_COND(cond, message)      \
-do {                                            \
-    if (!(cond)) {                              \
-        std::cout << "LOG WRN: " << message << std::endl;       \
-    }                                           \
-} while (false)                                 \
-
-#define STORM_LOG_INFO(message)                 \
-do {                                            \
-    std::cout << "LOG INF: " << message << std::endl;            \
-} while (false)                                 \
-
-#define STORM_LOG_INFO_COND(cond, message)      \
-do {                                            \
-    if (!(cond)) {                              \
-        std::cout << "LOG INF: " << message << std::endl;        \
-    }                                           \
-} while (false)                                 \
-
-#define STORM_LOG_ERROR(message)                \
-do {                                                \
-    std::stringstream __ss;                         \
-     __ss << message;                 \
-     std::cout << "LOG ERR: " << __ss.str() << std::endl;          \
-} while (false)                                 \
+#define STORM_LOG_WARN(message)                                \
+do {                                                           \
+    if(storm_runtime_loglevel >= STORM_LOGLEVEL_WARN) {        \
+        std::stringstream __ss;                                \
+        __ss << message;                                       \
+        std::cout << "LOG WRN: " << message << std::endl;      \
+    }                                                          \
+} while (false)                               
+
+#define STORM_LOG_WARN_COND(cond, message)                      \
+do {                                                            \
+    if (!(cond)) {                                              \
+        STORM_LOG_WARN(message);                                 \
+    }                                                           \
+} while (false)                                 
+
+#define STORM_LOG_INFO(message)                                 \
+do {                                                            \
+    if(storm_runtime_loglevel >= STORM_LOGLEVEL_INFO) {         \
+        std::stringstream __ss;                                 \
+        __ss << message;                                        \
+        std::cout << "LOG INF: " << message << std::endl;       \
+    }                                                           \
+} while (false)                                 
+
+#define STORM_LOG_INFO_COND(cond, message)                      \
+do {                                                            \
+    if (!(cond)) {                                              \
+        STORM_LOG_INFO(message);                                \
+    }                                                           \
+} while (false)                                 
+
+#define STORM_LOG_ERROR(message)                                \
+do {                                                            \
+    if(storm_runtime_loglevel >= STORM_LOGLEVEL_ERROR) {        \
+        std::stringstream __ss;                                 \
+        __ss << message;                                        \
+        std::cout << "LOG ERR: " << message << std::endl;       \
+    }                                                           \
+} while (false)                                                 \
 
 #define STORM_LOG_ERROR_COND(cond, message)     \
 do {                                            \
     if (!(cond)) {                              \
-        STORM_LOG_ERROR(message)        \
+        STORM_LOG_ERROR(message);               \
     }                                           \
 } while (false)                                 \
 
-#define STORM_GLOBAL_LOGLEVEL_INFO() \
-do { \
+#define STORM_GLOBAL_LOGLEVEL_INFO()                \
+do {                                                \
+storm_runtime_loglevel = STORM_LOGLEVEL_INFO;       \
 } while (false)
 
-#define STORM_GLOBAL_LOGLEVEL_DEBUG() \
-do { \
+#define STORM_GLOBAL_LOGLEVEL_DEBUG()               \
+do {                                                \
+storm_runtime_loglevel = STORM_LOGLEVEL_DEBUG;      \
 } while(false)
     
-#define STORM_GLOBAL_LOGLEVEL_TRACE() \
-do { \
+#define STORM_GLOBAL_LOGLEVEL_TRACE()               \
+do {                                                \
+storm_runtime_loglevel = STORM_LOGLEVEL_TRACE;      \
 } while(false)
 
-
 #else 
 // Include the parts necessary for Log4cplus.
 #include "log4cplus/logger.h"

From fcd98793eecf279eba99d2cff6b45d4ef493d0dc Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Thu, 25 Feb 2016 11:44:02 +0100
Subject: [PATCH 19/23] fixed supp for log4cplus

Former-commit-id: 7e0b2c449fa78bf216a8e581165baf034484b4a3
---
 src/utility/initialize.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/utility/initialize.cpp b/src/utility/initialize.cpp
index 72e3fd964..e7909d8ef 100644
--- a/src/utility/initialize.cpp
+++ b/src/utility/initialize.cpp
@@ -4,7 +4,11 @@
 #include "src/settings/SettingsManager.h"
 #include "src/settings/modules/DebugSettings.h"
 
+
 #ifdef STORM_LOGGING_FRAMEWORK
+#include "log4cplus/consoleappender.h"
+#include "log4cplus/fileappender.h"
+
 log4cplus::Logger logger;
 log4cplus::Logger printer;
 #else 

From 6818c6dc0d8da01869368d630dbdd0a92079b61e Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Thu, 25 Feb 2016 13:44:58 +0100
Subject: [PATCH 20/23] Fixed tests when no log4plus is available.

Former-commit-id: f1ae81376c79043b32e8a05f2a9b5c1a1bed4227
---
 test/functional/storm-functional-tests.cpp   | 17 +++++++++++------
 test/performance/storm-performance-tests.cpp | 14 ++++++++++----
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp
index 5051bb659..e206561e0 100644
--- a/test/functional/storm-functional-tests.cpp
+++ b/test/functional/storm-functional-tests.cpp
@@ -2,21 +2,25 @@
 #include <list>
 #include <string>
 
+#include "storm-config.h"
+
 #include "gtest/gtest.h"
+#ifdef STORM_LOGGING_FRAMEWORK
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 #include "log4cplus/consoleappender.h"
 #include "log4cplus/fileappender.h"
 
-#include "storm-config.h"
-#include "src/settings/SettingsManager.h"
-
 log4cplus::Logger logger;
+#endif
+
+#include "src/settings/SettingsManager.h"
 
 /*!
  * Initializes the logging framework.
  */
 void setUpLogging() {
+#ifdef STORM_LOGGING_FRAMEWORK
 	logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
 	logger.setLogLevel(log4cplus::ERROR_LOG_LEVEL);
 	log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log"));
@@ -24,7 +28,7 @@ void setUpLogging() {
 	fileLogAppender->setThreshold(log4cplus::FATAL_LOG_LEVEL);
 	fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n")));
 	logger.addAppender(fileLogAppender);
-
+#endif
 	// Uncomment these lines to enable console logging output
 	// log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender());
 	// consoleLogAppender->setName("mainConsoleAppender");
@@ -39,9 +43,10 @@ int main(int argc, char* argv[]) {
 	testing::InitGoogleTest(&argc, argv);
 
     int result = RUN_ALL_TESTS();
-    
+#ifdef STORM_LOGGING_FRAMEWORK
     logger.closeNestedAppenders();
-
+#endif
+    
 	std::list<std::string> untestedModules;
 #ifndef STORM_HAVE_GUROBI
 	untestedModules.push_back("Gurobi");
diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp
index 0c29f19c8..3291d6823 100644
--- a/test/performance/storm-performance-tests.cpp
+++ b/test/performance/storm-performance-tests.cpp
@@ -1,19 +1,24 @@
 #include <iostream>
 
 #include "gtest/gtest.h"
+#include "storm-config.h"
+
+
+#include "src/settings/SettingsManager.h"
+#ifdef STORM_LOGGING_FRAMEWORK
 #include "log4cplus/logger.h"
 #include "log4cplus/loggingmacros.h"
 #include "log4cplus/consoleappender.h"
 #include "log4cplus/fileappender.h"
 
-#include "src/settings/SettingsManager.h"
-
 log4cplus::Logger logger;
+#endif
 
 /*!
  * Initializes the logging framework.
  */
 void setUpLogging() {
+#ifdef STORM_LOGGING_FRAMEWORK
 	logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
 	logger.setLogLevel(log4cplus::WARN_LOG_LEVEL);
 	log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-performance-tests.log"));
@@ -21,7 +26,7 @@ void setUpLogging() {
 	fileLogAppender->setThreshold(log4cplus::WARN_LOG_LEVEL);
 	fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n")));
 	logger.addAppender(fileLogAppender);
-
+#endif 
 	// Uncomment these lines to enable console logging output
 	// log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender());
 	// consoleLogAppender->setName("mainConsoleAppender");
@@ -36,7 +41,8 @@ int main(int argc, char* argv[]) {
 	testing::InitGoogleTest(&argc, argv);
 
     int result = RUN_ALL_TESTS();
-    
+#ifdef STORM_LOGGING_FRAMEWORK
     logger.closeNestedAppenders();
+#endif
     return result;
 }

From 8c2cb4887f73e41bc30d9ef2ae7de9543ba4dba2 Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Thu, 25 Feb 2016 13:49:36 +0100
Subject: [PATCH 21/23] Cmake option to disable debug and trace outputs

Former-commit-id: 9758862579554eb3f83af62c09cfef5e4dbcd06c
---
 CMakeLists.txt       |  1 +
 src/utility/macros.h | 32 ++++++++++++++++++++++++++++++--
 storm-config.h.in    |  2 ++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 38c216d00..e19b6266d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,7 @@ option(USE_CARL "Sets whether carl should be included." ON)
 option(FORCE_COLOR "Force color output" OFF)
 option(STORM_COMPILE_WITH_CCACHE "Compile using CCache" ON)
 option(STORM_LOGGING_FRAMEWORK "Use a framework for logging" OFF)
+option(STORM_LOG_DISABLE_DEBUG "Disable log and trace message support" OFF)
 set(GUROBI_ROOT "" CACHE STRING "A hint to the root directory of Gurobi (optional).")
 set(Z3_ROOT "" CACHE STRING "A hint to the root directory of Z3 (optional).")
 set(CUDA_ROOT "" CACHE STRING "The root directory of CUDA.")
diff --git a/src/utility/macros.h b/src/utility/macros.h
index 769825139..db1394380 100644
--- a/src/utility/macros.h
+++ b/src/utility/macros.h
@@ -16,6 +16,12 @@ extern int storm_runtime_loglevel;
 #define STORM_LOGLEVEL_DEBUG 3
 #define STORM_LOGLEVEL_TRACE 4
 
+#ifdef STORM_LOG_DISABLE_DEBUG
+#define STORM_LOG_DISABLE_TRACE
+#endif
+
+
+#ifndef STORM_LOG_DISABLE_DEBUG
 #define STORM_LOG_DEBUG(message)                                    \
 do {                                                                \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) {            \
@@ -24,15 +30,26 @@ do {                                                                \
         std::cout << "LOG DBG: " << __ss.str() << std::endl;        \
     }                                                               \
 } while (false)
+#else
+#define STORM_LOG_DEBUG(message)                                    \
+do {                                                                \
+} while (false)                                                        
+#endif
 
+#ifndef STORM_LOG_DISABLE_TRACE
 #define STORM_LOG_TRACE(message)                                \
 do {                                                            \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) {        \
         std::stringstream __ss;                                 \
         __ss << message;                                        \
-        std::cout << "LOG TRC: " << message << std::endl;       \
+        std::cout << "LOG TRC: " << __ss.str() << std::endl;       \
     }                                                           \
 } while(false)  
+#else
+#define STORM_LOG_TRACE(message)                                \
+do {                                                            \
+} while (false)    
+#endif
 
 
 // Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set.
@@ -112,15 +129,26 @@ do {                                                \
 storm_runtime_loglevel = STORM_LOGLEVEL_INFO;       \
 } while (false)
 
+#ifndef STORM_LOG_DISABLE_DEBUG
 #define STORM_GLOBAL_LOGLEVEL_DEBUG()               \
 do {                                                \
 storm_runtime_loglevel = STORM_LOGLEVEL_DEBUG;      \
 } while(false)
-    
+#else 
+#define STORM_GLOBAL_LOGLEVEL_DEBUG()               \
+std::cout << "***** warning ***** loglevel debug is not compiled\n"
+#endif 
+
+#ifndef STORM_LOG_DISABLE_TRACE
 #define STORM_GLOBAL_LOGLEVEL_TRACE()               \
 do {                                                \
 storm_runtime_loglevel = STORM_LOGLEVEL_TRACE;      \
 } while(false)
+#else
+#define STORM_GLOBAL_LOGLEVEL_TRACE()               \
+std::cout << "***** warning ***** loglevel trace is not compiled\n"
+#endif
+
 
 #else 
 // Include the parts necessary for Log4cplus.
diff --git a/storm-config.h.in b/storm-config.h.in
index e7fbd50e6..7000bd141 100644
--- a/storm-config.h.in
+++ b/storm-config.h.in
@@ -46,4 +46,6 @@
 
 #cmakedefine STORM_LOGGING_FRAMEWORK
 
+#cmakedefine STORM_LOG_DISABLE_DEBUG
+
 #endif // STORM_GENERATED_STORMCONFIG_H_

From 9c30394b33ce72e4a7b467743910061ae8c49d09 Mon Sep 17 00:00:00 2001
From: Mavo <matthias.volk@rwth-aachen.de>
Date: Thu, 25 Feb 2016 14:59:27 +0100
Subject: [PATCH 22/23] Finalize sparse for failed, failsafe, dontcare

Former-commit-id: 722285c8d5e4c4d350ae56150bb287f1c8c5d298
---
 src/storage/dft/DFTElements.cpp | 13 +++++++---
 src/storage/dft/DFTElements.h   | 42 ++++++++++++++++-----------------
 src/storage/dft/DFTState.cpp    |  8 ++++---
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/src/storage/dft/DFTElements.cpp b/src/storage/dft/DFTElements.cpp
index 7bb8c2cf5..3f1d30017 100644
--- a/src/storage/dft/DFTElements.cpp
+++ b/src/storage/dft/DFTElements.cpp
@@ -17,17 +17,24 @@ namespace storm {
                     return false;
                 }
             }
+            
+            bool hasParentSpare = false;
+
             // Check that no parent can fail anymore
             for(DFTGatePointer const& parent : mParents) {
                 if(state.isOperational(parent->id())) {
                     return false;
                 }
+                if (parent->isSpareGate()) {
+                    hasParentSpare = true;
+                }
             }
             
-            
-        
-
             state.setDontCare(mId);
+            if (hasParentSpare && !state.isActive(mId)) {
+                // Activate child for consistency in failed spares
+                state.activate(mId);
+            }
             return true;
         }
 
diff --git a/src/storage/dft/DFTElements.h b/src/storage/dft/DFTElements.h
index 48318d0ae..0b970355f 100644
--- a/src/storage/dft/DFTElements.h
+++ b/src/storage/dft/DFTElements.h
@@ -387,10 +387,6 @@ namespace storm {
                     queues.checkRestrictionLater(restr);
                 }
                 state.setFailed(this->mId);
-                // TODO can this be moved towards DFTSpare?
-                if (this->isSpareGate()) {
-                    this->finalizeSpare(state);
-                }
                 this->childrenDontCare(state, queues);
             }
 
@@ -401,30 +397,13 @@ namespace storm {
                     }
                 }
                 state.setFailsafe(this->mId);
-                if (this->isSpareGate()) {
-                    this->finalizeSpare(state);
-                }
                 this->childrenDontCare(state, queues);
             }
-
+            
             void childrenDontCare(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
                 queues.propagateDontCare(mChildren);
             }
 
-            /**
-             * Finish failed/failsafe spare gate by activating the children and setting the useIndex to the maximum value.
-             * This prevents multiple fail states with different usages or activations.
-             * @param state The current state.
-             */
-            void finalizeSpare(DFTState<ValueType>& state) const {
-                state.finalizeUses(this->mId);
-                for (auto child : this->children()) {
-                    if (!state.isActive(child->id())) {
-                        state.activate(child->id());
-                    }
-                }
-            }
-
             bool hasFailsafeChild(DFTState<ValueType>& state) const {
                 for(auto const& child : mChildren) {
                     if(state.isFailsafe(child->id()))
@@ -959,6 +938,24 @@ namespace storm {
                 return true;
             }
             
+            void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                DFTGate<ValueType>::fail(state, queues);
+                state.finalizeUses(this->mId);
+            }
+            
+            void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                DFTGate<ValueType>::failsafe(state, queues);
+                state.finalizeUses(this->mId);
+            }
+            
+            bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if (DFTGate<ValueType>::checkDontCareAnymore(state, queues)) {
+                    state.finalizeUses(this->mId);
+                    return true;
+                }
+                return false;
+            }
+            
             void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
                 if(state.isOperational(this->mId)) {
                     size_t uses = state.uses(this->mId);
@@ -979,6 +976,7 @@ namespace storm {
                     }
                 }
             }
+
         };
         
         template<typename ValueType>
diff --git a/src/storage/dft/DFTState.cpp b/src/storage/dft/DFTState.cpp
index 8af84255c..7d3b25c8a 100644
--- a/src/storage/dft/DFTState.cpp
+++ b/src/storage/dft/DFTState.cpp
@@ -179,7 +179,6 @@ namespace storm {
             size_t activationIndex = mStateGenerationInfo.getSpareActivationIndex(repr);
             assert(!mStatus[activationIndex]);
             mStatus.set(activationIndex);
-            propagateActivation(repr);
         }
 
         template<typename ValueType>
@@ -190,11 +189,14 @@ namespace storm {
             
         template<typename ValueType>
         void DFTState<ValueType>::propagateActivation(size_t representativeId) {
+            if (representativeId != mDft.getTopLevelIndex()) {
+                activate(representativeId);
+            }
             for(size_t elem : mDft.module(representativeId)) {
                 if(mDft.getElement(elem)->isColdBasicElement() && isOperational(elem)) {
                     mIsCurrentlyFailableBE.push_back(elem);
                 } else if (mDft.getElement(elem)->isSpareGate() && !isActive(uses(elem))) {
-                    activate(uses(elem));
+                    propagateActivation(uses(elem));
                 }
             }
         }
@@ -245,7 +247,7 @@ namespace storm {
                 if(!hasFailed(childId) && !isUsed(childId)) {
                     setUses(spareId, childId);
                     if(isActive(currentlyUses)) {
-                        activate(childId);
+                        propagateActivation(childId);
                     }
                     return true;
                 }

From fde7b71933e809cb1cc7e4d0513db9e4d050065b Mon Sep 17 00:00:00 2001
From: sjunges <sebastian.junges@rwth-aachen.de>
Date: Thu, 25 Feb 2016 15:20:06 +0100
Subject: [PATCH 23/23] Nice printing when no logging framework is enabled

Former-commit-id: 783fe7eea12722d4abc1b0187353ddef50ed84e7
---
 src/utility/macros.h | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/utility/macros.h b/src/utility/macros.h
index db1394380..4f70b1691 100644
--- a/src/utility/macros.h
+++ b/src/utility/macros.h
@@ -21,13 +21,19 @@ extern int storm_runtime_loglevel;
 #endif
 
 
+#define __SHORT_FORM_OF_FILE__ \
+(strrchr(__FILE__,'/') \
+? strrchr(__FILE__,'/')+1 \
+: __FILE__ \
+)
+
 #ifndef STORM_LOG_DISABLE_DEBUG
 #define STORM_LOG_DEBUG(message)                                    \
 do {                                                                \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) {            \
         std::stringstream __ss;                                     \
         __ss << message;                                            \
-        std::cout << "LOG DBG: " << __ss.str() << std::endl;        \
+        std::cout << "DEBUG (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " <<  __ss.str() << std::endl;        \
     }                                                               \
 } while (false)
 #else
@@ -42,7 +48,7 @@ do {                                                            \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) {        \
         std::stringstream __ss;                                 \
         __ss << message;                                        \
-        std::cout << "LOG TRC: " << __ss.str() << std::endl;       \
+        std::cout << "TRACE (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " <<  __ss.str() << std::endl;       \
     }                                                           \
 } while(false)  
 #else
@@ -57,7 +63,7 @@ do {                                                            \
 #define STORM_LOG_ASSERT(cond, message)                     \
 do {                                                        \
 if (!(cond)) {                                              \
-std::cout << "ASSERT FAILED: " << message << std::endl;     \
+std::cout << "ASSERT FAILED (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " <<  message << std::endl;     \
 assert(cond);                                               \
 }                                                           \
 } while (false)                                 
@@ -69,7 +75,7 @@ assert(cond);                                               \
 #define STORM_LOG_THROW(cond, exception, message)               \
 do {                                                            \
     if (!(cond)) {                                              \
-        std::cout << "LOG ERR: " << message << std::endl;       \
+        std::cout << "ERROR (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " <<  message << std::endl;       \
         throw exception() << message;                           \
     }                                                           \
 } while (false)                                
@@ -81,7 +87,7 @@ do {                                                           \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_WARN) {        \
         std::stringstream __ss;                                \
         __ss << message;                                       \
-        std::cout << "LOG WRN: " << message << std::endl;      \
+        std::cout << "WARN  (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " <<  __ss.str() << std::endl;      \
     }                                                          \
 } while (false)                               
 
@@ -97,7 +103,7 @@ do {                                                            \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_INFO) {         \
         std::stringstream __ss;                                 \
         __ss << message;                                        \
-        std::cout << "LOG INF: " << message << std::endl;       \
+        std::cout << "INFO  (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl;       \
     }                                                           \
 } while (false)                                 
 
@@ -113,7 +119,7 @@ do {                                                            \
     if(storm_runtime_loglevel >= STORM_LOGLEVEL_ERROR) {        \
         std::stringstream __ss;                                 \
         __ss << message;                                        \
-        std::cout << "LOG ERR: " << message << std::endl;       \
+        std::cout << "ERROR (" << __SHORT_FORM_OF_FILE__  << ":" << __LINE__ << "): " << __ss.str() << std::endl;       \
     }                                                           \
 } while (false)                                                 \